Coverage Report

Created: 2026-04-12 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Modules/_datetimemodule.c
Line
Count
Source
1
/*  C implementation of the datetime module */
2
3
/* bpo-35081: Defining this prevents including the C API capsule;
4
 * internal versions of the  Py*_Check macros which do not require
5
 * the capsule are defined below */
6
#define _PY_DATETIME_IMPL
7
8
#ifndef Py_BUILD_CORE_BUILTIN
9
#  define Py_BUILD_CORE_MODULE 1
10
#endif
11
12
#include "Python.h"
13
#include "pycore_long.h"          // _PyLong_GetOne()
14
#include "pycore_object.h"        // _PyObject_Init()
15
#include "pycore_time.h"          // _PyTime_ObjectToTime_t()
16
#include "pycore_tuple.h"         // _PyTuple_FromPair
17
#include "pycore_unicodeobject.h" // _PyUnicode_Copy()
18
#include "pycore_initconfig.h"    // _PyStatus_OK()
19
#include "pycore_pyatomic_ft_wrappers.h"
20
21
#include "datetime.h"
22
23
24
#include <time.h>
25
26
#ifdef MS_WINDOWS
27
#  include <winsock2.h>         /* struct timeval */
28
#endif
29
30
31
/* forward declarations */
32
static PyTypeObject PyDateTime_DateType;
33
static PyTypeObject PyDateTime_DateTimeType;
34
static PyTypeObject PyDateTime_TimeType;
35
static PyTypeObject PyDateTime_DeltaType;
36
static PyTypeObject PyDateTime_TZInfoType;
37
static PyTypeObject PyDateTime_TimeZoneType;
38
39
40
typedef struct {
41
    /* Module heap types. */
42
    PyTypeObject *isocalendar_date_type;
43
44
    /* Conversion factors. */
45
    PyObject *us_per_ms;       // 1_000
46
    PyObject *us_per_second;   // 1_000_000
47
    PyObject *us_per_minute;   // 1e6 * 60 as Python int
48
    PyObject *us_per_hour;     // 1e6 * 3600 as Python int
49
    PyObject *us_per_day;      // 1e6 * 3600 * 24 as Python int
50
    PyObject *us_per_week;     // 1e6 * 3600 * 24 * 7 as Python int
51
    PyObject *seconds_per_day; // 3600 * 24 as Python int
52
53
    /* The interned Unix epoch datetime instance */
54
    PyObject *epoch;
55
} datetime_state;
56
57
/* The module has a fixed number of static objects, due to being exposed
58
 * through the datetime C-API.  There are five types exposed directly,
59
 * one type exposed indirectly, and one singleton constant (UTC).
60
 *
61
 * Each of these objects is hidden behind a macro in the same way as
62
 * the per-module objects stored in module state.  The macros for the
63
 * static objects don't need to be passed a state, but the consistency
64
 * of doing so is more clear.  We use a dedicated noop macro, NO_STATE,
65
 * to make the special case obvious.
66
 *
67
 * The casting macros perform a simple fast pointer cast without
68
 * checking the runtime type. In the future, we may decide whether
69
 * to include that check and whether to provide a fast pointer cast
70
 * macro for pointers known to be of correct time.
71
 */
72
73
#define NO_STATE NULL
74
75
0
#define DATE_TYPE(st) &PyDateTime_DateType
76
21.5k
#define DATETIME_TYPE(st) &PyDateTime_DateTimeType
77
0
#define TIME_TYPE(st) &PyDateTime_TimeType
78
114
#define DELTA_TYPE(st) &PyDateTime_DeltaType
79
#define TZINFO_TYPE(st) &PyDateTime_TZInfoType
80
76
#define TIMEZONE_TYPE(st) &PyDateTime_TimeZoneType
81
0
#define ISOCALENDAR_DATE_TYPE(st) st->isocalendar_date_type
82
83
24
#define PyDate_CAST(op) ((PyDateTime_Date *)(op))
84
0
#define PyDate_Check(op) PyObject_TypeCheck(op, DATE_TYPE(NO_STATE))
85
#define PyDate_CheckExact(op) Py_IS_TYPE(op, DATE_TYPE(NO_STATE))
86
87
21.6k
#define PyDateTime_CAST(op) ((PyDateTime_DateTime *)(op))
88
10.7k
#define PyDateTime_Check(op) PyObject_TypeCheck(op, DATETIME_TYPE(NO_STATE))
89
#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, DATETIME_TYPE(NO_STATE))
90
91
158
#define PyTime_CAST(op) ((PyDateTime_Time *)(op))
92
0
#define PyTime_Check(op) PyObject_TypeCheck(op, TIME_TYPE(NO_STATE))
93
#define PyTime_CheckExact(op) Py_IS_TYPE(op, TIME_TYPE(NO_STATE))
94
95
34.4k
#define PyDelta_CAST(op) ((PyDateTime_Delta *)(op))
96
10.8k
#define PyDelta_Check(op) PyObject_TypeCheck(op, DELTA_TYPE(NO_STATE))
97
#define PyDelta_CheckExact(op) Py_IS_TYPE(op, DELTA_TYPE(NO_STATE))
98
99
#define PyTZInfo_CAST(op) ((PyDateTime_TZInfo *)(op))
100
36
#define PyTZInfo_Check(op) PyObject_TypeCheck(op, TZINFO_TYPE(NO_STATE))
101
#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, TZINFO_TYPE(NO_STATE))
102
103
0
#define PyTimeZone_CAST(op) ((PyDateTime_TimeZone *)(op))
104
0
#define PyTimezone_Check(op) PyObject_TypeCheck(op, TIMEZONE_TYPE(NO_STATE))
105
106
#define PyIsoCalendarDate_CAST(op) ((PyDateTime_IsoCalendarDate *)(op))
107
108
4
#define CONST_US_PER_MS(st) st->us_per_ms
109
21.8k
#define CONST_US_PER_SECOND(st) st->us_per_second
110
4
#define CONST_US_PER_MINUTE(st) st->us_per_minute
111
4
#define CONST_US_PER_HOUR(st) st->us_per_hour
112
8
#define CONST_US_PER_DAY(st) st->us_per_day
113
0
#define CONST_US_PER_WEEK(st) st->us_per_week
114
10.9k
#define CONST_SEC_PER_DAY(st) st->seconds_per_day
115
0
#define CONST_EPOCH(st) st->epoch
116
0
#define CONST_UTC(st) ((PyObject *)&utc_timezone)
117
118
static datetime_state *
119
get_module_state(PyObject *module)
120
23.0k
{
121
23.0k
    void *state = _PyModule_GetState(module);
122
23.0k
    assert(state != NULL);
123
23.0k
    return (datetime_state *)state;
124
23.0k
}
125
126
127
21.8k
#define INTERP_KEY ((PyObject *)&_Py_ID(cached_datetime_module))
128
129
static PyObject *
130
get_current_module(PyInterpreterState *interp)
131
21.8k
{
132
21.8k
    PyObject *mod = NULL;
133
134
21.8k
    PyObject *dict = PyInterpreterState_GetDict(interp);
135
21.8k
    if (dict == NULL) {
136
0
        goto error;
137
0
    }
138
21.8k
    PyObject *ref = NULL;
139
21.8k
    if (PyDict_GetItemRef(dict, INTERP_KEY, &ref) < 0) {
140
0
        goto error;
141
0
    }
142
21.8k
    if (ref != NULL) {
143
21.8k
        if (ref != Py_None) {
144
21.8k
            (void)PyWeakref_GetRef(ref, &mod);
145
21.8k
            if (mod == Py_None) {
146
0
                Py_CLEAR(mod);
147
0
            }
148
21.8k
            Py_DECREF(ref);
149
21.8k
        }
150
21.8k
    }
151
21.8k
    return mod;
152
153
0
error:
154
0
    assert(PyErr_Occurred());
155
0
    return NULL;
156
21.8k
}
157
158
static PyModuleDef datetimemodule;
159
160
static datetime_state *
161
_get_current_state(PyObject **p_mod)
162
21.8k
{
163
21.8k
    PyInterpreterState *interp = PyInterpreterState_Get();
164
21.8k
    PyObject *mod = get_current_module(interp);
165
21.8k
    if (mod == NULL) {
166
0
        assert(!PyErr_Occurred());
167
0
        if (PyErr_Occurred()) {
168
0
            return NULL;
169
0
        }
170
        /* The static types can outlive the module,
171
         * so we must re-import the module. */
172
0
        mod = PyImport_ImportModule("_datetime");
173
0
        if (mod == NULL) {
174
0
            return NULL;
175
0
        }
176
0
    }
177
21.8k
    datetime_state *st = get_module_state(mod);
178
21.8k
    *p_mod = mod;
179
21.8k
    return st;
180
21.8k
}
181
182
#define GET_CURRENT_STATE(MOD_VAR)  \
183
21.8k
    _get_current_state(&MOD_VAR)
184
#define RELEASE_CURRENT_STATE(ST_VAR, MOD_VAR)  \
185
21.8k
    Py_DECREF(MOD_VAR)
186
187
static int
188
set_current_module(PyInterpreterState *interp, PyObject *mod)
189
14
{
190
14
    assert(mod != NULL);
191
14
    PyObject *dict = PyInterpreterState_GetDict(interp);
192
14
    if (dict == NULL) {
193
0
        return -1;
194
0
    }
195
14
    PyObject *ref = PyWeakref_NewRef(mod, NULL);
196
14
    if (ref == NULL) {
197
0
        return -1;
198
0
    }
199
14
    int rc = PyDict_SetItem(dict, INTERP_KEY, ref);
200
14
    Py_DECREF(ref);
201
14
    return rc;
202
14
}
203
204
static void
205
clear_current_module(PyInterpreterState *interp, PyObject *expected)
206
0
{
207
0
    PyObject *exc = PyErr_GetRaisedException();
208
209
0
    PyObject *dict = PyInterpreterState_GetDict(interp);
210
0
    if (dict == NULL) {
211
0
        goto error;
212
0
    }
213
214
0
    if (expected != NULL) {
215
0
        PyObject *ref = NULL;
216
0
        if (PyDict_GetItemRef(dict, INTERP_KEY, &ref) < 0) {
217
0
            goto error;
218
0
        }
219
0
        if (ref != NULL && ref != Py_None) {
220
0
            PyObject *current = NULL;
221
0
            int rc = PyWeakref_GetRef(ref, &current);
222
            /* We only need "current" for pointer comparison. */
223
0
            Py_XDECREF(current);
224
0
            Py_DECREF(ref);
225
0
            if (rc < 0) {
226
0
                goto error;
227
0
            }
228
0
            if (current != expected) {
229
0
                goto finally;
230
0
            }
231
0
        }
232
0
    }
233
234
    /* We use None to identify that the module was previously loaded. */
235
0
    if (PyDict_SetItem(dict, INTERP_KEY, Py_None) < 0) {
236
0
        goto error;
237
0
    }
238
239
0
    goto finally;
240
241
0
error:
242
0
    PyErr_FormatUnraisable("Exception ignored while clearing _datetime module");
243
244
0
finally:
245
0
    PyErr_SetRaisedException(exc);
246
0
}
247
248
249
/* We require that C int be at least 32 bits, and use int virtually
250
 * everywhere.  In just a few cases we use a temp long, where a Python
251
 * API returns a C long.  In such cases, we have to ensure that the
252
 * final result fits in a C int (this can be an issue on 64-bit boxes).
253
 */
254
#if SIZEOF_INT < 4
255
#       error "_datetime.c requires that C int have at least 32 bits"
256
#endif
257
258
24.6k
#define MINYEAR 1
259
13.4k
#define MAXYEAR 9999
260
8.56k
#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
261
262
/* Nine decimal digits is easy to communicate, and leaves enough room
263
 * so that two delta days can be added w/o fear of overflowing a signed
264
 * 32-bit int, and with plenty of room left over to absorb any possible
265
 * carries from adding seconds.
266
 */
267
43.0k
#define MAX_DELTA_DAYS 999999999
268
269
/* Rename the long macros in datetime.h to more reasonable short names. */
270
21.7k
#define GET_YEAR                PyDateTime_GET_YEAR
271
21.7k
#define GET_MONTH               PyDateTime_GET_MONTH
272
21.7k
#define GET_DAY                 PyDateTime_GET_DAY
273
21.5k
#define DATE_GET_HOUR           PyDateTime_DATE_GET_HOUR
274
21.5k
#define DATE_GET_MINUTE         PyDateTime_DATE_GET_MINUTE
275
21.5k
#define DATE_GET_SECOND         PyDateTime_DATE_GET_SECOND
276
10.7k
#define DATE_GET_MICROSECOND    PyDateTime_DATE_GET_MICROSECOND
277
8
#define DATE_GET_FOLD           PyDateTime_DATE_GET_FOLD
278
279
/* Date accessors for date and datetime. */
280
11.2k
#define SET_YEAR(o, v)          (((o)->data[0] = ((v) & 0xff00) >> 8), \
281
11.2k
                 ((o)->data[1] = ((v) & 0x00ff)))
282
11.2k
#define SET_MONTH(o, v)         (PyDateTime_GET_MONTH(o) = (v))
283
11.2k
#define SET_DAY(o, v)           (PyDateTime_GET_DAY(o) = (v))
284
285
/* Date/Time accessors for datetime. */
286
10.9k
#define DATE_SET_HOUR(o, v)     (PyDateTime_DATE_GET_HOUR(o) = (v))
287
10.9k
#define DATE_SET_MINUTE(o, v)   (PyDateTime_DATE_GET_MINUTE(o) = (v))
288
10.9k
#define DATE_SET_SECOND(o, v)   (PyDateTime_DATE_GET_SECOND(o) = (v))
289
#define DATE_SET_MICROSECOND(o, v)      \
290
10.9k
    (((o)->data[7] = ((v) & 0xff0000) >> 16), \
291
10.9k
     ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
292
10.9k
     ((o)->data[9] = ((v) & 0x0000ff)))
293
10.9k
#define DATE_SET_FOLD(o, v)   (PyDateTime_DATE_GET_FOLD(o) = (v))
294
295
/* Time accessors for time. */
296
0
#define TIME_GET_HOUR           PyDateTime_TIME_GET_HOUR
297
0
#define TIME_GET_MINUTE         PyDateTime_TIME_GET_MINUTE
298
0
#define TIME_GET_SECOND         PyDateTime_TIME_GET_SECOND
299
0
#define TIME_GET_MICROSECOND    PyDateTime_TIME_GET_MICROSECOND
300
0
#define TIME_GET_FOLD           PyDateTime_TIME_GET_FOLD
301
230
#define TIME_SET_HOUR(o, v)     (PyDateTime_TIME_GET_HOUR(o) = (v))
302
230
#define TIME_SET_MINUTE(o, v)   (PyDateTime_TIME_GET_MINUTE(o) = (v))
303
230
#define TIME_SET_SECOND(o, v)   (PyDateTime_TIME_GET_SECOND(o) = (v))
304
#define TIME_SET_MICROSECOND(o, v)      \
305
230
    (((o)->data[3] = ((v) & 0xff0000) >> 16), \
306
230
     ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
307
230
     ((o)->data[5] = ((v) & 0x0000ff)))
308
230
#define TIME_SET_FOLD(o, v)   (PyDateTime_TIME_GET_FOLD(o) = (v))
309
310
/* Delta accessors for timedelta. */
311
11.6k
#define GET_TD_DAYS(o)          (PyDelta_CAST(o)->days)
312
11.5k
#define GET_TD_SECONDS(o)       (PyDelta_CAST(o)->seconds)
313
11.2k
#define GET_TD_MICROSECONDS(o)  (PyDelta_CAST(o)->microseconds)
314
315
20.5k
#define SET_TD_DAYS(o, v)       ((o)->days = (v))
316
20.5k
#define SET_TD_SECONDS(o, v)    ((o)->seconds = (v))
317
20.5k
#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
318
319
32.5k
#define HASTZINFO               _PyDateTime_HAS_TZINFO
320
0
#define GET_TIME_TZINFO         PyDateTime_TIME_GET_TZINFO
321
28
#define GET_DT_TZINFO           PyDateTime_DATE_GET_TZINFO
322
/* M is a char or int claiming to be a valid month.  The macro is equivalent
323
 * to the two-sided Python test
324
 *      1 <= M <= 12
325
 */
326
0
#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
327
328
static int check_tzinfo_subclass(PyObject *p);
329
330
/*[clinic input]
331
module datetime
332
class datetime.datetime "PyDateTime_DateTime *" "get_datetime_state()->datetime_type"
333
class datetime.date "PyDateTime_Date *" "get_datetime_state()->date_type"
334
class datetime.time "PyDateTime_Time *" "get_datetime_state()->time_type"
335
class datetime.IsoCalendarDate "PyDateTime_IsoCalendarDate *" "get_datetime_state()->isocalendar_date_type"
336
class datetime.timedelta "PyDateTime_Delta *" "&PyDateTime_DeltaType"
337
class datetime.timezone "PyDateTime_TimeZone *" "&PyDateTime_TimeZoneType"
338
[clinic start generated code]*/
339
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c54b9adf60082f0d]*/
340
341
#include "clinic/_datetimemodule.c.h"
342
343
344
/* ---------------------------------------------------------------------------
345
 * Math utilities.
346
 */
347
348
/* k = i+j overflows iff k differs in sign from both inputs,
349
 * iff k^i has sign bit set and k^j has sign bit set,
350
 * iff (k^i)&(k^j) has sign bit set.
351
 */
352
#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
353
    ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
354
355
/* Compute Python divmod(x, y), returning the quotient and storing the
356
 * remainder into *r.  The quotient is the floor of x/y, and that's
357
 * the real point of this.  C will probably truncate instead (C99
358
 * requires truncation; C89 left it implementation-defined).
359
 * Simplification:  we *require* that y > 0 here.  That's appropriate
360
 * for all the uses made of it.  This simplifies the code and makes
361
 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
362
 * overflow case).
363
 */
364
static int
365
divmod(int x, int y, int *r)
366
28.2k
{
367
28.2k
    int quo;
368
369
28.2k
    assert(y > 0);
370
28.2k
    quo = x / y;
371
28.2k
    *r = x - quo * y;
372
28.2k
    if (*r < 0) {
373
4.10k
        --quo;
374
4.10k
        *r += y;
375
4.10k
    }
376
28.2k
    assert(0 <= *r && *r < y);
377
28.2k
    return quo;
378
28.2k
}
379
380
/* Nearest integer to m / n for integers m and n. Half-integer results
381
 * are rounded to even.
382
 */
383
static PyObject *
384
divide_nearest(PyObject *m, PyObject *n)
385
0
{
386
0
    PyObject *result;
387
0
    PyObject *temp;
388
389
0
    temp = _PyLong_DivmodNear(m, n);
390
0
    if (temp == NULL)
391
0
        return NULL;
392
0
    result = Py_NewRef(PyTuple_GET_ITEM(temp, 0));
393
0
    Py_DECREF(temp);
394
395
0
    return result;
396
0
}
397
398
/* ---------------------------------------------------------------------------
399
 * General calendrical helper functions
400
 */
401
402
/* For each month ordinal in 1..12, the number of days in that month,
403
 * and the number of days before that month in the same year.  These
404
 * are correct for non-leap years only.
405
 */
406
static const int _days_in_month[] = {
407
    0, /* unused; this vector uses 1-based indexing */
408
    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
409
};
410
411
static const int _days_before_month[] = {
412
    0, /* unused; this vector uses 1-based indexing */
413
    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
414
};
415
416
/* year -> 1 if leap year, else 0. */
417
static int
418
is_leap(int year)
419
15.0k
{
420
    /* Cast year to unsigned.  The result is the same either way, but
421
     * C can generate faster code for unsigned mod than for signed
422
     * mod (especially for % 4 -- a good compiler should just grab
423
     * the last 2 bits when the LHS is unsigned).
424
     */
425
15.0k
    const unsigned int ayear = (unsigned int)year;
426
15.0k
    return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
427
15.0k
}
428
429
/* year, month -> number of days in that month in that year */
430
static int
431
days_in_month(int year, int month)
432
24.2k
{
433
24.2k
    assert(month >= 1);
434
24.2k
    assert(month <= 12);
435
24.2k
    if (month == 2 && is_leap(year))
436
260
        return 29;
437
23.9k
    else
438
23.9k
        return _days_in_month[month];
439
24.2k
}
440
441
/* year, month -> number of days in year preceding first day of month */
442
static int
443
days_before_month(int year, int month)
444
30.4k
{
445
30.4k
    int days;
446
447
30.4k
    assert(month >= 1);
448
30.4k
    assert(month <= 12);
449
30.4k
    days = _days_before_month[month];
450
30.4k
    if (month > 2 && is_leap(year))
451
6.83k
        ++days;
452
30.4k
    return days;
453
30.4k
}
454
455
/* year -> number of days before January 1st of year.  Remember that we
456
 * start with year 1, so days_before_year(1) == 0.
457
 */
458
static int
459
days_before_year(int year)
460
19.5k
{
461
19.5k
    int y = year - 1;
462
    /* This is incorrect if year <= 0; we really want the floor
463
     * here.  But so long as MINYEAR is 1, the smallest year this
464
     * can see is 1.
465
     */
466
19.5k
    assert (year >= 1);
467
19.5k
    return y*365 + y/4 - y/100 + y/400;
468
19.5k
}
469
470
/* Number of days in 4, 100, and 400 year cycles.  That these have
471
 * the correct values is asserted in the module init function.
472
 */
473
17.1k
#define DI4Y    1461    /* days_before_year(5); days in 4 years */
474
17.1k
#define DI100Y  36524   /* days_before_year(101); days in 100 years */
475
17.1k
#define DI400Y  146097  /* days_before_year(401); days in 400 years  */
476
477
/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
478
static void
479
ord_to_ymd(int ordinal, int *year, int *month, int *day)
480
8.56k
{
481
8.56k
    int n, n1, n4, n100, n400, leapyear, preceding;
482
483
    /* ordinal is a 1-based index, starting at 1-Jan-1.  The pattern of
484
     * leap years repeats exactly every 400 years.  The basic strategy is
485
     * to find the closest 400-year boundary at or before ordinal, then
486
     * work with the offset from that boundary to ordinal.  Life is much
487
     * clearer if we subtract 1 from ordinal first -- then the values
488
     * of ordinal at 400-year boundaries are exactly those divisible
489
     * by DI400Y:
490
     *
491
     *    D  M   Y            n              n-1
492
     *    -- --- ----        ----------     ----------------
493
     *    31 Dec -400        -DI400Y       -DI400Y -1
494
     *     1 Jan -399         -DI400Y +1   -DI400Y      400-year boundary
495
     *    ...
496
     *    30 Dec  000        -1             -2
497
     *    31 Dec  000         0             -1
498
     *     1 Jan  001         1              0          400-year boundary
499
     *     2 Jan  001         2              1
500
     *     3 Jan  001         3              2
501
     *    ...
502
     *    31 Dec  400         DI400Y        DI400Y -1
503
     *     1 Jan  401         DI400Y +1     DI400Y      400-year boundary
504
     */
505
8.56k
    assert(ordinal >= 1);
506
8.56k
    --ordinal;
507
8.56k
    n400 = ordinal / DI400Y;
508
8.56k
    n = ordinal % DI400Y;
509
8.56k
    *year = n400 * 400 + 1;
510
511
    /* Now n is the (non-negative) offset, in days, from January 1 of
512
     * year, to the desired date.  Now compute how many 100-year cycles
513
     * precede n.
514
     * Note that it's possible for n100 to equal 4!  In that case 4 full
515
     * 100-year cycles precede the desired day, which implies the
516
     * desired day is December 31 at the end of a 400-year cycle.
517
     */
518
8.56k
    n100 = n / DI100Y;
519
8.56k
    n = n % DI100Y;
520
521
    /* Now compute how many 4-year cycles precede it. */
522
8.56k
    n4 = n / DI4Y;
523
8.56k
    n = n % DI4Y;
524
525
    /* And now how many single years.  Again n1 can be 4, and again
526
     * meaning that the desired day is December 31 at the end of the
527
     * 4-year cycle.
528
     */
529
8.56k
    n1 = n / 365;
530
8.56k
    n = n % 365;
531
532
8.56k
    *year += n100 * 100 + n4 * 4 + n1;
533
8.56k
    if (n1 == 4 || n100 == 4) {
534
9
        assert(n == 0);
535
9
        *year -= 1;
536
9
        *month = 12;
537
9
        *day = 31;
538
9
        return;
539
9
    }
540
541
    /* Now the year is correct, and n is the offset from January 1.  We
542
     * find the month via an estimate that's either exact or one too
543
     * large.
544
     */
545
8.55k
    leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
546
8.55k
    assert(leapyear == is_leap(*year));
547
8.55k
    *month = (n + 50) >> 5;
548
8.55k
    preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
549
8.55k
    if (preceding > n) {
550
        /* estimate is too large */
551
2.22k
        *month -= 1;
552
2.22k
        preceding -= days_in_month(*year, *month);
553
2.22k
    }
554
8.55k
    n -= preceding;
555
8.55k
    assert(0 <= n);
556
8.55k
    assert(n < days_in_month(*year, *month));
557
558
8.55k
    *day = n + 1;
559
8.55k
}
560
561
/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
562
static int
563
ymd_to_ord(int year, int month, int day)
564
19.5k
{
565
19.5k
    return days_before_year(year) + days_before_month(year, month) + day;
566
19.5k
}
567
568
/* Day of week, where Monday==0, ..., Sunday==6.  1/1/1 was a Monday. */
569
static int
570
weekday(int year, int month, int day)
571
10.9k
{
572
10.9k
    return (ymd_to_ord(year, month, day) + 6) % 7;
573
10.9k
}
574
575
/* Ordinal of the Monday starting week 1 of the ISO year.  Week 1 is the
576
 * first calendar week containing a Thursday.
577
 */
578
static int
579
iso_week1_monday(int year)
580
0
{
581
0
    int first_day = ymd_to_ord(year, 1, 1);     /* ord of 1/1 */
582
    /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
583
0
    int first_weekday = (first_day + 6) % 7;
584
    /* ordinal of closest Monday at or before 1/1 */
585
0
    int week1_monday  = first_day - first_weekday;
586
587
0
    if (first_weekday > 3)      /* if 1/1 was Fri, Sat, Sun */
588
0
        week1_monday += 7;
589
0
    return week1_monday;
590
0
}
591
592
static int
593
iso_to_ymd(const int iso_year, const int iso_week, const int iso_day,
594
0
           int *year, int *month, int *day) {
595
    // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5)
596
0
    if (iso_year < MINYEAR || iso_year > MAXYEAR) {
597
0
        return -4;
598
0
    }
599
0
    if (iso_week <= 0 || iso_week >= 53) {
600
0
        int out_of_range = 1;
601
0
        if (iso_week == 53) {
602
            // ISO years have 53 weeks in it on years starting with a Thursday
603
            // and on leap years starting on Wednesday
604
0
            int first_weekday = weekday(iso_year, 1, 1);
605
0
            if (first_weekday == 3 || (first_weekday == 2 && is_leap(iso_year))) {
606
0
                out_of_range = 0;
607
0
            }
608
0
        }
609
610
0
        if (out_of_range) {
611
0
            return -2;
612
0
        }
613
0
    }
614
615
0
    if (iso_day <= 0 || iso_day >= 8) {
616
0
        return -3;
617
0
    }
618
619
    // Convert (Y, W, D) to (Y, M, D) in-place
620
0
    int day_1 = iso_week1_monday(iso_year);
621
622
0
    int day_offset = (iso_week - 1)*7 + iso_day - 1;
623
624
0
    ord_to_ymd(day_1 + day_offset, year, month, day);
625
0
    return 0;
626
0
}
627
628
629
/* ---------------------------------------------------------------------------
630
 * Range checkers.
631
 */
632
633
/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS.  If so, return 0.
634
 * If not, raise OverflowError and return -1.
635
 */
636
static int
637
check_delta_day_range(int days)
638
21.5k
{
639
21.5k
    if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
640
21.5k
        return 0;
641
0
    PyErr_Format(PyExc_OverflowError,
642
0
                 "days=%d; must have magnitude <= %d",
643
0
                 days, MAX_DELTA_DAYS);
644
0
    return -1;
645
21.5k
}
646
647
/* Check that date arguments are in range.  Return 0 if they are.  If they
648
 * aren't, raise ValueError and return -1.
649
 */
650
static int
651
check_date_args(int year, int month, int day)
652
11.2k
{
653
654
11.2k
    if (year < MINYEAR || year > MAXYEAR) {
655
1
        PyErr_Format(PyExc_ValueError,
656
1
                     "year must be in %d..%d, not %d", MINYEAR, MAXYEAR, year);
657
1
        return -1;
658
1
    }
659
11.2k
    if (month < 1 || month > 12) {
660
0
        PyErr_Format(PyExc_ValueError,
661
0
                     "month must be in 1..12, not %d", month);
662
0
        return -1;
663
0
    }
664
11.2k
    int dim = days_in_month(year, month);
665
11.2k
    if (day < 1 || day > dim) {
666
2
        PyErr_Format(PyExc_ValueError,
667
2
                     "day %i must be in range 1..%d for month %i in year %i",
668
2
                     day, dim, month, year);
669
2
        return -1;
670
2
    }
671
11.2k
    return 0;
672
11.2k
}
673
674
/* Check that time arguments are in range.  Return 0 if they are.  If they
675
 * aren't, raise ValueError and return -1.
676
 */
677
static int
678
check_time_args(int h, int m, int s, int us, int fold)
679
11.1k
{
680
11.1k
    if (h < 0 || h > 23) {
681
0
        PyErr_Format(PyExc_ValueError, "hour must be in 0..23, not %i", h);
682
0
        return -1;
683
0
    }
684
11.1k
    if (m < 0 || m > 59) {
685
0
        PyErr_Format(PyExc_ValueError, "minute must be in 0..59, not %i", m);
686
0
        return -1;
687
0
    }
688
11.1k
    if (s < 0 || s > 59) {
689
0
        PyErr_Format(PyExc_ValueError, "second must be in 0..59, not %i", s);
690
0
        return -1;
691
0
    }
692
11.1k
    if (us < 0 || us > 999999) {
693
0
        PyErr_Format(PyExc_ValueError,
694
0
                     "microsecond must be in 0..999999, not %i", us);
695
0
        return -1;
696
0
    }
697
11.1k
    if (fold != 0 && fold != 1) {
698
0
        PyErr_Format(PyExc_ValueError,
699
0
                     "fold must be either 0 or 1, not %i", fold);
700
0
        return -1;
701
0
    }
702
11.1k
    return 0;
703
11.1k
}
704
705
/* ---------------------------------------------------------------------------
706
 * Normalization utilities.
707
 */
708
709
/* One step of a mixed-radix conversion.  A "hi" unit is equivalent to
710
 * factor "lo" units.  factor must be > 0.  If *lo is less than 0, or
711
 * at least factor, enough of *lo is converted into "hi" units so that
712
 * 0 <= *lo < factor.  The input values must be such that int overflow
713
 * is impossible.
714
 */
715
static void
716
normalize_pair(int *hi, int *lo, int factor)
717
52.8k
{
718
52.8k
    assert(factor > 0);
719
52.8k
    assert(lo != hi);
720
52.8k
    if (*lo < 0 || *lo >= factor) {
721
28.2k
        const int num_hi = divmod(*lo, factor, lo);
722
28.2k
        const int new_hi = *hi + num_hi;
723
28.2k
        assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
724
28.2k
        *hi = new_hi;
725
28.2k
    }
726
52.8k
    assert(0 <= *lo && *lo < factor);
727
52.8k
}
728
729
/* Fiddle days (d), seconds (s), and microseconds (us) so that
730
 *      0 <= *s < 24*3600
731
 *      0 <= *us < 1000000
732
 * The input values must be such that the internals don't overflow.
733
 * The way this routine is used, we don't get close.
734
 */
735
static void
736
normalize_d_s_us(int *d, int *s, int *us)
737
10.4k
{
738
10.4k
    if (*us < 0 || *us >= 1000000) {
739
0
        normalize_pair(s, us, 1000000);
740
        /* |s| can't be bigger than about
741
         * |original s| + |original us|/1000000 now.
742
         */
743
744
0
    }
745
10.4k
    if (*s < 0 || *s >= 24*3600) {
746
9.71k
        normalize_pair(d, s, 24*3600);
747
        /* |d| can't be bigger than about
748
         * |original d| +
749
         * (|original s| + |original us|/1000000) / (24*3600) now.
750
         */
751
9.71k
    }
752
10.4k
    assert(0 <= *s && *s < 24*3600);
753
10.4k
    assert(0 <= *us && *us < 1000000);
754
10.4k
}
755
756
/* Fiddle years (y), months (m), and days (d) so that
757
 *      1 <= *m <= 12
758
 *      1 <= *d <= days_in_month(*y, *m)
759
 * The input values must be such that the internals don't overflow.
760
 * The way this routine is used, we don't get close.
761
 */
762
static int
763
normalize_y_m_d(int *y, int *m, int *d)
764
10.7k
{
765
10.7k
    int dim;            /* # of days in month */
766
767
    /* In actual use, m is always the month component extracted from a
768
     * date/datetime object.  Therefore it is always in [1, 12] range.
769
     */
770
771
10.7k
    assert(1 <= *m && *m <= 12);
772
773
    /* Now only day can be out of bounds (year may also be out of bounds
774
     * for a datetime object, but we don't care about that here).
775
     * If day is out of bounds, what to do is arguable, but at least the
776
     * method here is principled and explainable.
777
     */
778
10.7k
    dim = days_in_month(*y, *m);
779
10.7k
    if (*d < 1 || *d > dim) {
780
        /* Move day-1 days from the first of the month.  First try to
781
         * get off cheap if we're only one day out of range
782
         * (adjustments for timezone alone can't be worse than that).
783
         */
784
8.59k
        if (*d == 0) {
785
0
            --*m;
786
0
            if (*m > 0)
787
0
                *d = days_in_month(*y, *m);
788
0
            else {
789
0
                --*y;
790
0
                *m = 12;
791
0
                *d = 31;
792
0
            }
793
0
        }
794
8.59k
        else if (*d == dim + 1) {
795
            /* move forward a day */
796
32
            ++*m;
797
32
            *d = 1;
798
32
            if (*m > 12) {
799
0
                *m = 1;
800
0
                ++*y;
801
0
            }
802
32
        }
803
8.56k
        else {
804
8.56k
            int ordinal = ymd_to_ord(*y, *m, 1) +
805
8.56k
                                      *d - 1;
806
8.56k
            if (ordinal < 1 || ordinal > MAXORDINAL) {
807
0
                goto error;
808
8.56k
            } else {
809
8.56k
                ord_to_ymd(ordinal, y, m, d);
810
8.56k
                return 0;
811
8.56k
            }
812
8.56k
        }
813
8.59k
    }
814
10.7k
    assert(*m > 0);
815
2.20k
    assert(*d > 0);
816
2.20k
    if (MINYEAR <= *y && *y <= MAXYEAR)
817
2.20k
        return 0;
818
0
 error:
819
0
    PyErr_SetString(PyExc_OverflowError,
820
0
            "date value out of range");
821
0
    return -1;
822
823
2.20k
}
824
825
/* Fiddle out-of-bounds months and days so that the result makes some kind
826
 * of sense.  The parameters are both inputs and outputs.  Returns < 0 on
827
 * failure, where failure means the adjusted year is out of bounds.
828
 */
829
static int
830
normalize_date(int *year, int *month, int *day)
831
10.7k
{
832
10.7k
    return normalize_y_m_d(year, month, day);
833
10.7k
}
834
835
/* Force all the datetime fields into range.  The parameters are both
836
 * inputs and outputs.  Returns < 0 on error.
837
 */
838
static int
839
normalize_datetime(int *year, int *month, int *day,
840
                   int *hour, int *minute, int *second,
841
                   int *microsecond)
842
10.7k
{
843
10.7k
    normalize_pair(second, microsecond, 1000000);
844
10.7k
    normalize_pair(minute, second, 60);
845
10.7k
    normalize_pair(hour, minute, 60);
846
10.7k
    normalize_pair(day, hour, 24);
847
10.7k
    return normalize_date(year, month, day);
848
10.7k
}
849
850
/* ---------------------------------------------------------------------------
851
 * Basic object allocation:  tp_alloc implementations.  These allocate
852
 * Python objects of the right size and type, and do the Python object-
853
 * initialization bit.  If there's not enough memory, they return NULL after
854
 * setting MemoryError.  All data members remain uninitialized trash.
855
 *
856
 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
857
 * member is needed.  This is ugly, imprecise, and possibly insecure.
858
 * tp_basicsize for the time and datetime types is set to the size of the
859
 * struct that has room for the tzinfo member, so subclasses in Python will
860
 * allocate enough space for a tzinfo member whether or not one is actually
861
 * needed.  That's the "ugly and imprecise" parts.  The "possibly insecure"
862
 * part is that PyType_GenericAlloc() (which subclasses in Python end up
863
 * using) just happens today to effectively ignore the nitems argument
864
 * when tp_itemsize is 0, which it is for these type objects.  If that
865
 * changes, perhaps the callers of tp_alloc slots in this file should
866
 * be changed to force a 0 nitems argument unless the type being allocated
867
 * is a base type implemented in this file (so that tp_alloc is time_alloc
868
 * or datetime_alloc below, which know about the nitems abuse).
869
 */
870
871
static PyObject *
872
time_alloc(PyTypeObject *type, Py_ssize_t aware)
873
230
{
874
230
    size_t size = aware ? sizeof(PyDateTime_Time) : sizeof(_PyDateTime_BaseTime);
875
230
    PyObject *self = (PyObject *)PyObject_Malloc(size);
876
230
    if (self == NULL) {
877
0
        return PyErr_NoMemory();
878
0
    }
879
230
    _PyObject_Init(self, type);
880
230
    return self;
881
230
}
882
883
static PyObject *
884
datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
885
10.9k
{
886
10.9k
    size_t size = aware ? sizeof(PyDateTime_DateTime) : sizeof(_PyDateTime_BaseDateTime);
887
10.9k
    PyObject *self = (PyObject *)PyObject_Malloc(size);
888
10.9k
    if (self == NULL) {
889
0
        return PyErr_NoMemory();
890
0
    }
891
10.9k
    _PyObject_Init(self, type);
892
10.9k
    return self;
893
10.9k
}
894
895
/* ---------------------------------------------------------------------------
896
 * Helpers for setting object fields.  These work on pointers to the
897
 * appropriate base class.
898
 */
899
900
/* For date and datetime. */
901
static void
902
set_date_fields(PyDateTime_Date *self, int y, int m, int d)
903
11.2k
{
904
11.2k
    self->hashcode = -1;
905
11.2k
    SET_YEAR(self, y);
906
11.2k
    SET_MONTH(self, m);
907
11.2k
    SET_DAY(self, d);
908
11.2k
}
909
910
/* ---------------------------------------------------------------------------
911
 * String parsing utilities and helper functions
912
 */
913
914
static unsigned char
915
0
is_digit(const char c) {
916
0
    return ((unsigned int)(c - '0')) < 10;
917
0
}
918
919
static const char *
920
parse_digits(const char *ptr, int *var, size_t num_digits)
921
0
{
922
0
    for (size_t i = 0; i < num_digits; ++i) {
923
0
        unsigned int tmp = (unsigned int)(*(ptr++) - '0');
924
0
        if (tmp > 9) {
925
0
            return NULL;
926
0
        }
927
0
        *var *= 10;
928
0
        *var += (signed int)tmp;
929
0
    }
930
931
0
    return ptr;
932
0
}
933
934
static int
935
parse_isoformat_date(const char *dtstr, const size_t len, int *year, int *month, int *day)
936
0
{
937
    /* Parse the date components of the result of date.isoformat()
938
     *
939
     *  Return codes:
940
     *       0:  Success
941
     *      -1:  Failed to parse date component
942
     *      -2:  Inconsistent date separator usage
943
     *      -3:  Failed to parse ISO week.
944
     *      -4:  Failed to parse ISO day.
945
     *      -5, -6, -7: Failure in iso_to_ymd
946
     */
947
0
    const char *p = dtstr;
948
0
    p = parse_digits(p, year, 4);
949
0
    if (NULL == p) {
950
0
        return -1;
951
0
    }
952
953
0
    const unsigned char uses_separator = (*p == '-');
954
0
    if (uses_separator) {
955
0
        ++p;
956
0
    }
957
958
0
    if(*p == 'W') {
959
        // This is an isocalendar-style date string
960
0
        p++;
961
0
        int iso_week = 0;
962
0
        int iso_day = 0;
963
964
0
        p = parse_digits(p, &iso_week, 2);
965
0
        if (NULL == p) {
966
0
            return -3;
967
0
        }
968
969
0
        assert(p > dtstr);
970
0
        if ((size_t)(p - dtstr) < len) {
971
0
            if (uses_separator && *(p++) != '-') {
972
0
                return -2;
973
0
            }
974
975
0
            p = parse_digits(p, &iso_day, 1);
976
0
            if (NULL == p) {
977
0
                return -4;
978
0
            }
979
0
        } else {
980
0
            iso_day = 1;
981
0
        }
982
983
0
        int rv = iso_to_ymd(*year, iso_week, iso_day, year, month, day);
984
0
        if (rv) {
985
0
            return -3 + rv;
986
0
        } else {
987
0
            return 0;
988
0
        }
989
0
    }
990
991
0
    p = parse_digits(p, month, 2);
992
0
    if (NULL == p) {
993
0
        return -1;
994
0
    }
995
996
0
    if (uses_separator && *(p++) != '-') {
997
0
        return -2;
998
0
    }
999
0
    p = parse_digits(p, day, 2);
1000
0
    if (p == NULL) {
1001
0
        return -1;
1002
0
    }
1003
0
    return 0;
1004
0
}
1005
1006
static int
1007
parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour,
1008
                  int *minute, int *second, int *microsecond)
1009
0
{
1010
0
    *hour = *minute = *second = *microsecond = 0;
1011
0
    const char *p = tstr;
1012
0
    const char *p_end = tstr_end;
1013
0
    int *vals[3] = {hour, minute, second};
1014
    // This is initialized to satisfy an erroneous compiler warning.
1015
0
    unsigned char has_separator = 1;
1016
1017
    // Parse [HH[:?MM[:?SS]]]
1018
0
    for (size_t i = 0; i < 3; ++i) {
1019
0
        p = parse_digits(p, vals[i], 2);
1020
0
        if (NULL == p) {
1021
0
            return -3;
1022
0
        }
1023
1024
0
        char c = *(p++);
1025
0
        if (i == 0) {
1026
0
            has_separator = (c == ':');
1027
0
        }
1028
1029
0
        if (p >= p_end) {
1030
0
            return c != '\0';
1031
0
        }
1032
0
        else if (has_separator && (c == ':')) {
1033
0
            if (i == 2) {
1034
0
                return -4;  // Malformed microsecond separator
1035
0
            }
1036
0
            continue;
1037
0
        }
1038
0
        else if (c == '.' || c == ',') {
1039
0
            if (i < 2) {
1040
0
                return -3; // Decimal mark on hour or minute
1041
0
            }
1042
0
            break;
1043
0
        } else if (!has_separator) {
1044
0
            --p;
1045
0
        } else {
1046
0
            return -4;  // Malformed time separator
1047
0
        }
1048
0
    }
1049
1050
    // Parse fractional components
1051
0
    size_t len_remains = p_end - p;
1052
0
    size_t to_parse = len_remains;
1053
0
    if (len_remains >= 6) {
1054
0
        to_parse = 6;
1055
0
    }
1056
1057
0
    p = parse_digits(p, microsecond, to_parse);
1058
0
    if (NULL == p) {
1059
0
        return -3;
1060
0
    }
1061
1062
0
    static int correction[] = {
1063
0
        100000, 10000, 1000, 100, 10
1064
0
    };
1065
1066
0
    if (to_parse < 6) {
1067
0
        *microsecond *= correction[to_parse-1];
1068
0
    }
1069
1070
0
    while (is_digit(*p)){
1071
0
        ++p; // skip truncated digits
1072
0
    }
1073
1074
    // Return 1 if it's not the end of the string
1075
0
    return *p != '\0';
1076
0
}
1077
1078
static int
1079
parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute,
1080
                     int *second, int *microsecond, int *tzoffset,
1081
                     int *tzmicrosecond)
1082
0
{
1083
    // Parse the time portion of a datetime.isoformat() string
1084
    //
1085
    // Return codes:
1086
    //      0:  Success (no tzoffset)
1087
    //      1:  Success (with tzoffset)
1088
    //     -3:  Failed to parse time component
1089
    //     -4:  Failed to parse time separator
1090
    //     -5:  Malformed timezone string
1091
    //     -6:  Timezone fields are not in range
1092
1093
0
    const char *p = dtstr;
1094
0
    const char *p_end = dtstr + dtlen;
1095
1096
0
    const char *tzinfo_pos = p;
1097
0
    do {
1098
0
        if (*tzinfo_pos == 'Z' || *tzinfo_pos == '+' || *tzinfo_pos == '-') {
1099
0
            break;
1100
0
        }
1101
0
    } while (++tzinfo_pos < p_end);
1102
1103
0
    int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second,
1104
0
                               microsecond);
1105
1106
0
    if (rv < 0) {
1107
0
        return rv;
1108
0
    }
1109
0
    else if (tzinfo_pos == p_end) {
1110
        // We know that there's no time zone, so if there's stuff at the
1111
        // end of the string it's an error.
1112
0
        if (rv == 1) {
1113
0
            return -5;
1114
0
        }
1115
0
        else {
1116
0
            return 0;
1117
0
        }
1118
0
    }
1119
1120
    // Special case UTC / Zulu time.
1121
0
    if (*tzinfo_pos == 'Z') {
1122
0
        *tzoffset = 0;
1123
0
        *tzmicrosecond = 0;
1124
1125
0
        if (*(tzinfo_pos + 1) != '\0') {
1126
0
            return -5;
1127
0
        } else {
1128
0
            return 1;
1129
0
        }
1130
0
    }
1131
1132
0
    int tzsign = (*tzinfo_pos == '-') ? -1 : 1;
1133
0
    tzinfo_pos++;
1134
0
    int tzhour = 0, tzminute = 0, tzsecond = 0;
1135
0
    rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end, &tzhour, &tzminute, &tzsecond,
1136
0
                           tzmicrosecond);
1137
1138
    // Check if timezone fields are in range
1139
0
    if (check_time_args(tzhour, tzminute, tzsecond, *tzmicrosecond, 0) < 0) {
1140
0
        return -6;
1141
0
    }
1142
1143
0
    *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond);
1144
0
    *tzmicrosecond *= tzsign;
1145
1146
0
    return rv ? -5 : 1;
1147
0
}
1148
1149
/* ---------------------------------------------------------------------------
1150
 * Create various objects, mostly without range checking.
1151
 */
1152
1153
/* Create a date instance with no range checking. */
1154
static PyObject *
1155
new_date_ex(int year, int month, int day, PyTypeObject *type)
1156
266
{
1157
266
    PyDateTime_Date *self;
1158
1159
266
    if (check_date_args(year, month, day) < 0) {
1160
2
        return NULL;
1161
2
    }
1162
1163
264
    self = (PyDateTime_Date *)(type->tp_alloc(type, 0));
1164
264
    if (self != NULL)
1165
264
        set_date_fields(self, year, month, day);
1166
264
    return (PyObject *)self;
1167
266
}
1168
1169
#define new_date(year, month, day) \
1170
0
    new_date_ex(year, month, day, DATE_TYPE(NO_STATE))
1171
1172
// Forward declaration
1173
static PyObject *
1174
new_datetime_ex(int, int, int, int, int, int, int, PyObject *, PyTypeObject *);
1175
1176
/* Create date instance with no range checking, or call subclass constructor */
1177
static PyObject *
1178
new_date_subclass_ex(int year, int month, int day, PyTypeObject *cls)
1179
0
{
1180
0
    PyObject *result;
1181
    // We have "fast path" constructors for two subclasses: date and datetime
1182
0
    if (cls == DATE_TYPE(NO_STATE)) {
1183
0
        result = new_date_ex(year, month, day, cls);
1184
0
    }
1185
0
    else if (cls == DATETIME_TYPE(NO_STATE)) {
1186
0
        result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None, cls);
1187
0
    }
1188
0
    else {
1189
0
        result = PyObject_CallFunction((PyObject *)cls, "iii", year, month, day);
1190
0
    }
1191
1192
0
    return result;
1193
0
}
1194
1195
/* Create a datetime instance with no range checking. */
1196
static PyObject *
1197
new_datetime_ex2(int year, int month, int day, int hour, int minute,
1198
                 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
1199
10.9k
{
1200
10.9k
    PyDateTime_DateTime *self;
1201
10.9k
    char aware = tzinfo != Py_None;
1202
1203
10.9k
    if (check_date_args(year, month, day) < 0) {
1204
1
        return NULL;
1205
1
    }
1206
10.9k
    if (check_time_args(hour, minute, second, usecond, fold) < 0) {
1207
0
        return NULL;
1208
0
    }
1209
10.9k
    if (check_tzinfo_subclass(tzinfo) < 0) {
1210
0
        return NULL;
1211
0
    }
1212
1213
10.9k
    self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
1214
10.9k
    if (self != NULL) {
1215
10.9k
        self->hastzinfo = aware;
1216
10.9k
        set_date_fields((PyDateTime_Date *)self, year, month, day);
1217
10.9k
        DATE_SET_HOUR(self, hour);
1218
10.9k
        DATE_SET_MINUTE(self, minute);
1219
10.9k
        DATE_SET_SECOND(self, second);
1220
10.9k
        DATE_SET_MICROSECOND(self, usecond);
1221
10.9k
        if (aware) {
1222
36
            self->tzinfo = Py_NewRef(tzinfo);
1223
36
        }
1224
10.9k
        DATE_SET_FOLD(self, fold);
1225
10.9k
    }
1226
10.9k
    return (PyObject *)self;
1227
10.9k
}
1228
1229
static PyObject *
1230
new_datetime_ex(int year, int month, int day, int hour, int minute,
1231
                int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
1232
0
{
1233
0
    return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
1234
0
                            tzinfo, 0, type);
1235
0
}
1236
1237
#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
1238
10.7k
    new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, DATETIME_TYPE(NO_STATE))
1239
1240
static PyObject *
1241
call_subclass_fold(PyTypeObject *cls, int fold, const char *format, ...)
1242
0
{
1243
0
    PyObject *kwargs = NULL, *res = NULL;
1244
0
    va_list va;
1245
1246
0
    va_start(va, format);
1247
0
    PyObject *args = Py_VaBuildValue(format, va);
1248
0
    va_end(va);
1249
0
    if (args == NULL) {
1250
0
        return NULL;
1251
0
    }
1252
0
    if (fold) {
1253
0
        kwargs = PyDict_New();
1254
0
        if (kwargs == NULL) {
1255
0
            goto Done;
1256
0
        }
1257
0
        PyObject *obj = PyLong_FromLong(fold);
1258
0
        if (obj == NULL) {
1259
0
            goto Done;
1260
0
        }
1261
0
        int err = PyDict_SetItemString(kwargs, "fold", obj);
1262
0
        Py_DECREF(obj);
1263
0
        if (err < 0) {
1264
0
            goto Done;
1265
0
        }
1266
0
    }
1267
0
    res = PyObject_Call((PyObject *)cls, args, kwargs);
1268
0
Done:
1269
0
    Py_DECREF(args);
1270
0
    Py_XDECREF(kwargs);
1271
0
    return res;
1272
0
}
1273
1274
static PyObject *
1275
new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute,
1276
                              int second, int usecond, PyObject *tzinfo,
1277
                              int fold, PyTypeObject *cls)
1278
10.7k
{
1279
10.7k
    PyObject* dt;
1280
10.7k
    if (cls == DATETIME_TYPE(NO_STATE)) {
1281
        // Use the fast path constructor
1282
10.7k
        dt = new_datetime(year, month, day, hour, minute, second, usecond,
1283
10.7k
                          tzinfo, fold);
1284
10.7k
    }
1285
0
    else {
1286
        // Subclass
1287
0
        dt = call_subclass_fold(cls, fold, "iiiiiiiO", year, month, day,
1288
0
                                hour, minute, second, usecond, tzinfo);
1289
0
    }
1290
1291
10.7k
    return dt;
1292
10.7k
}
1293
1294
static PyObject *
1295
new_datetime_subclass_ex(int year, int month, int day, int hour, int minute,
1296
                              int second, int usecond, PyObject *tzinfo,
1297
10.7k
                              PyTypeObject *cls) {
1298
10.7k
    return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
1299
10.7k
                                         second, usecond, tzinfo, 0,
1300
10.7k
                                         cls);
1301
10.7k
}
1302
1303
/* Create a time instance with no range checking. */
1304
static PyObject *
1305
new_time_ex2(int hour, int minute, int second, int usecond,
1306
             PyObject *tzinfo, int fold, PyTypeObject *type)
1307
230
{
1308
230
    PyDateTime_Time *self;
1309
230
    char aware = tzinfo != Py_None;
1310
1311
230
    if (check_time_args(hour, minute, second, usecond, fold) < 0) {
1312
0
        return NULL;
1313
0
    }
1314
230
    if (check_tzinfo_subclass(tzinfo) < 0) {
1315
0
        return NULL;
1316
0
    }
1317
1318
230
    self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
1319
230
    if (self != NULL) {
1320
230
        self->hastzinfo = aware;
1321
230
        self->hashcode = -1;
1322
230
        TIME_SET_HOUR(self, hour);
1323
230
        TIME_SET_MINUTE(self, minute);
1324
230
        TIME_SET_SECOND(self, second);
1325
230
        TIME_SET_MICROSECOND(self, usecond);
1326
230
        if (aware) {
1327
0
            self->tzinfo = Py_NewRef(tzinfo);
1328
0
        }
1329
230
        TIME_SET_FOLD(self, fold);
1330
230
    }
1331
230
    return (PyObject *)self;
1332
230
}
1333
1334
static PyObject *
1335
new_time_ex(int hour, int minute, int second, int usecond,
1336
            PyObject *tzinfo, PyTypeObject *type)
1337
0
{
1338
0
    return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
1339
0
}
1340
1341
#define new_time(hh, mm, ss, us, tzinfo, fold)  \
1342
0
    new_time_ex2(hh, mm, ss, us, tzinfo, fold, TIME_TYPE(NO_STATE))
1343
1344
static PyObject *
1345
new_time_subclass_fold_ex(int hour, int minute, int second, int usecond,
1346
                          PyObject *tzinfo, int fold, PyTypeObject *cls)
1347
0
{
1348
0
    PyObject *t;
1349
0
    if (cls == TIME_TYPE(NO_STATE)) {
1350
        // Use the fast path constructor
1351
0
        t = new_time(hour, minute, second, usecond, tzinfo, fold);
1352
0
    }
1353
0
    else {
1354
        // Subclass
1355
0
        t = call_subclass_fold(cls, fold, "iiiiO", hour, minute, second,
1356
0
                               usecond, tzinfo);
1357
0
    }
1358
1359
0
    return t;
1360
0
}
1361
1362
static PyDateTime_Delta * look_up_delta(int, int, int, PyTypeObject *);
1363
1364
/* Create a timedelta instance.  Normalize the members iff normalize is
1365
 * true.  Passing false is a speed optimization, if you know for sure
1366
 * that seconds and microseconds are already in their proper ranges.  In any
1367
 * case, raises OverflowError and returns NULL if the normalized days is out
1368
 * of range.
1369
 */
1370
static PyObject *
1371
new_delta_ex(int days, int seconds, int microseconds, int normalize,
1372
             PyTypeObject *type)
1373
21.5k
{
1374
21.5k
    PyDateTime_Delta *self;
1375
1376
21.5k
    if (normalize)
1377
10.4k
        normalize_d_s_us(&days, &seconds, &microseconds);
1378
21.5k
    assert(0 <= seconds && seconds < 24*3600);
1379
21.5k
    assert(0 <= microseconds && microseconds < 1000000);
1380
1381
21.5k
    if (check_delta_day_range(days) < 0)
1382
0
        return NULL;
1383
1384
21.5k
    self = look_up_delta(days, seconds, microseconds, type);
1385
21.5k
    if (self != NULL) {
1386
997
        return (PyObject *)self;
1387
997
    }
1388
21.5k
    assert(!PyErr_Occurred());
1389
1390
20.5k
    self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
1391
20.5k
    if (self != NULL) {
1392
20.5k
        self->hashcode = -1;
1393
20.5k
        SET_TD_DAYS(self, days);
1394
20.5k
        SET_TD_SECONDS(self, seconds);
1395
20.5k
        SET_TD_MICROSECONDS(self, microseconds);
1396
20.5k
    }
1397
20.5k
    return (PyObject *) self;
1398
21.5k
}
1399
1400
#define new_delta(d, s, us, normalize)  \
1401
82
    new_delta_ex(d, s, us, normalize, DELTA_TYPE(NO_STATE))
1402
1403
1404
typedef struct
1405
{
1406
    PyObject_HEAD
1407
    PyObject *offset;
1408
    PyObject *name;
1409
} PyDateTime_TimeZone;
1410
1411
static PyDateTime_TimeZone * look_up_timezone(PyObject *offset, PyObject *name);
1412
1413
/* Create new timezone instance checking offset range.  This
1414
   function does not check the name argument.  Caller must assure
1415
   that offset is a timedelta instance and name is either NULL
1416
   or a unicode object. */
1417
static PyObject *
1418
create_timezone(PyObject *offset, PyObject *name)
1419
76
{
1420
76
    PyDateTime_TimeZone *self;
1421
76
    PyTypeObject *type = TIMEZONE_TYPE(NO_STATE);
1422
1423
76
    assert(offset != NULL);
1424
76
    assert(PyDelta_Check(offset));
1425
76
    assert(name == NULL || PyUnicode_Check(name));
1426
1427
76
    self = look_up_timezone(offset, name);
1428
76
    if (self != NULL) {
1429
0
        return (PyObject *)self;
1430
0
    }
1431
76
    assert(!PyErr_Occurred());
1432
1433
76
    self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
1434
76
    if (self == NULL) {
1435
0
        return NULL;
1436
0
    }
1437
76
    self->offset = Py_NewRef(offset);
1438
76
    self->name = Py_XNewRef(name);
1439
76
    return (PyObject *)self;
1440
76
}
1441
1442
static int delta_bool(PyObject *op);
1443
static PyDateTime_TimeZone utc_timezone;
1444
1445
static PyObject *
1446
new_timezone(PyObject *offset, PyObject *name)
1447
4
{
1448
4
    assert(offset != NULL);
1449
4
    assert(PyDelta_Check(offset));
1450
4
    assert(name == NULL || PyUnicode_Check(name));
1451
1452
4
    if (name == NULL && delta_bool(offset) == 0) {
1453
0
        return Py_NewRef(CONST_UTC(NO_STATE));
1454
0
    }
1455
4
    if ((GET_TD_DAYS(offset) == -1 &&
1456
4
            GET_TD_SECONDS(offset) == 0 &&
1457
0
            GET_TD_MICROSECONDS(offset) < 1) ||
1458
4
        GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1459
0
        PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1460
0
                     " strictly between -timedelta(hours=24) and"
1461
0
                     " timedelta(hours=24), not %R", offset);
1462
0
        return NULL;
1463
0
    }
1464
1465
4
    return create_timezone(offset, name);
1466
4
}
1467
1468
/* ---------------------------------------------------------------------------
1469
 * tzinfo helpers.
1470
 */
1471
1472
/* Ensure that p is None or of a tzinfo subclass.  Return 0 if OK; if not
1473
 * raise TypeError and return -1.
1474
 */
1475
static int
1476
check_tzinfo_subclass(PyObject *p)
1477
11.1k
{
1478
11.1k
    if (p == Py_None || PyTZInfo_Check(p))
1479
11.1k
        return 0;
1480
0
    PyErr_Format(PyExc_TypeError,
1481
0
                 "tzinfo argument must be None or of a tzinfo subclass, "
1482
0
                 "not type '%s'",
1483
0
                 Py_TYPE(p)->tp_name);
1484
0
    return -1;
1485
11.1k
}
1486
1487
/* If self has a tzinfo member, return a BORROWED reference to it.  Else
1488
 * return NULL, which is NOT AN ERROR.  There are no error returns here,
1489
 * and the caller must not decref the result.
1490
 */
1491
static PyObject *
1492
get_tzinfo_member(PyObject *self)
1493
0
{
1494
0
    PyObject *tzinfo = NULL;
1495
1496
0
    if (PyDateTime_Check(self) && HASTZINFO(self))
1497
0
        tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
1498
0
    else if (PyTime_Check(self) && HASTZINFO(self))
1499
0
        tzinfo = ((PyDateTime_Time *)self)->tzinfo;
1500
1501
0
    return tzinfo;
1502
0
}
1503
1504
/* Call getattr(tzinfo, name)(tzinfoarg), and check the result.  tzinfo must
1505
 * be an instance of the tzinfo class.  If the method returns None, this
1506
 * returns None.  If the method doesn't return None or timedelta, TypeError is
1507
 * raised and this returns NULL.  If it returns a timedelta and the value is
1508
 * out of range or isn't a whole number of minutes, ValueError is raised and
1509
 * this returns NULL.  Else result is returned.
1510
 */
1511
static PyObject *
1512
call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
1513
8
{
1514
8
    PyObject *offset;
1515
1516
8
    assert(tzinfo != NULL);
1517
8
    assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
1518
8
    assert(tzinfoarg != NULL);
1519
1520
8
    if (tzinfo == Py_None)
1521
8
        Py_RETURN_NONE;
1522
0
    offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
1523
0
    if (offset == Py_None || offset == NULL)
1524
0
        return offset;
1525
0
    if (PyDelta_Check(offset)) {
1526
0
        if ((GET_TD_DAYS(offset) == -1 &&
1527
0
                GET_TD_SECONDS(offset) == 0 &&
1528
0
                GET_TD_MICROSECONDS(offset) < 1) ||
1529
0
            GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1530
0
            PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1531
0
                         " strictly between -timedelta(hours=24) and"
1532
0
                         " timedelta(hours=24), not %R", offset);
1533
0
            Py_DECREF(offset);
1534
0
            return NULL;
1535
0
        }
1536
0
    }
1537
0
    else {
1538
0
        PyErr_Format(PyExc_TypeError,
1539
0
                     "tzinfo.%s() must return None or "
1540
0
                     "timedelta, not '%.200s'",
1541
0
                     name, Py_TYPE(offset)->tp_name);
1542
0
        Py_DECREF(offset);
1543
0
        return NULL;
1544
0
    }
1545
1546
0
    return offset;
1547
0
}
1548
1549
/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
1550
 * result.  tzinfo must be an instance of the tzinfo class.  If utcoffset()
1551
 * returns None, call_utcoffset returns 0 and sets *none to 1.  If uctoffset()
1552
 * doesn't return None or timedelta, TypeError is raised and this returns -1.
1553
 * If utcoffset() returns an out of range timedelta,
1554
 * ValueError is raised and this returns -1.  Else *none is
1555
 * set to 0 and the offset is returned (as timedelta, positive east of UTC).
1556
 */
1557
static PyObject *
1558
call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
1559
8
{
1560
8
    return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
1561
8
}
1562
1563
/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
1564
 * result.  tzinfo must be an instance of the tzinfo class.  If dst()
1565
 * returns None, call_dst returns 0 and sets *none to 1.  If dst()
1566
 * doesn't return None or timedelta, TypeError is raised and this
1567
 * returns -1.  If dst() returns an invalid timedelta for a UTC offset,
1568
 * ValueError is raised and this returns -1.  Else *none is set to 0 and
1569
 * the offset is returned (as timedelta, positive east of UTC).
1570
 */
1571
static PyObject *
1572
call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
1573
0
{
1574
0
    return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
1575
0
}
1576
1577
/* Call tzinfo.tzname(tzinfoarg), and return the result.  tzinfo must be
1578
 * an instance of the tzinfo class or None.  If tzinfo isn't None, and
1579
 * tzname() doesn't return None or a string, TypeError is raised and this
1580
 * returns NULL.  If the result is a string, we ensure it is a Unicode
1581
 * string.
1582
 */
1583
static PyObject *
1584
call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
1585
0
{
1586
0
    PyObject *result;
1587
0
    assert(tzinfo != NULL);
1588
0
    assert(check_tzinfo_subclass(tzinfo) >= 0);
1589
0
    assert(tzinfoarg != NULL);
1590
1591
0
    if (tzinfo == Py_None)
1592
0
        Py_RETURN_NONE;
1593
1594
0
    result = PyObject_CallMethodOneArg(tzinfo, &_Py_ID(tzname), tzinfoarg);
1595
1596
0
    if (result == NULL || result == Py_None)
1597
0
        return result;
1598
1599
0
    if (!PyUnicode_Check(result)) {
1600
0
        PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1601
0
                     "return None or a string, not '%s'",
1602
0
                     Py_TYPE(result)->tp_name);
1603
0
        Py_SETREF(result, NULL);
1604
0
    }
1605
1606
0
    return result;
1607
0
}
1608
1609
/* repr is like "someclass(arg1, arg2)".  If tzinfo isn't None,
1610
 * stuff
1611
 *     ", tzinfo=" + repr(tzinfo)
1612
 * before the closing ")".
1613
 */
1614
static PyObject *
1615
append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1616
0
{
1617
0
    PyObject *temp;
1618
1619
0
    assert(PyUnicode_Check(repr));
1620
0
    assert(tzinfo);
1621
0
    if (tzinfo == Py_None)
1622
0
        return repr;
1623
    /* Get rid of the trailing ')'. */
1624
0
    assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1625
0
    temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1626
0
    Py_DECREF(repr);
1627
0
    if (temp == NULL)
1628
0
        return NULL;
1629
0
    repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1630
0
    Py_DECREF(temp);
1631
0
    return repr;
1632
0
}
1633
1634
/* repr is like "someclass(arg1, arg2)".  If fold isn't 0,
1635
 * stuff
1636
 *     ", fold=" + repr(tzinfo)
1637
 * before the closing ")".
1638
 */
1639
static PyObject *
1640
append_keyword_fold(PyObject *repr, int fold)
1641
0
{
1642
0
    PyObject *temp;
1643
1644
0
    assert(PyUnicode_Check(repr));
1645
0
    if (fold == 0)
1646
0
        return repr;
1647
    /* Get rid of the trailing ')'. */
1648
0
    assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1649
0
    temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1650
0
    Py_DECREF(repr);
1651
0
    if (temp == NULL)
1652
0
        return NULL;
1653
0
    repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1654
0
    Py_DECREF(temp);
1655
0
    return repr;
1656
0
}
1657
1658
static inline PyObject *
1659
tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds)
1660
0
{
1661
0
    PyObject *tzinfo;
1662
0
    if (rv == 1) {
1663
        // Create a timezone from offset in seconds (0 returns UTC)
1664
0
        if (tzoffset == 0) {
1665
0
            return Py_NewRef(CONST_UTC(NO_STATE));
1666
0
        }
1667
1668
0
        PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1);
1669
0
        if (delta == NULL) {
1670
0
            return NULL;
1671
0
        }
1672
0
        tzinfo = new_timezone(delta, NULL);
1673
0
        Py_DECREF(delta);
1674
0
    }
1675
0
    else {
1676
0
        tzinfo = Py_NewRef(Py_None);
1677
0
    }
1678
1679
0
    return tzinfo;
1680
0
}
1681
1682
/* ---------------------------------------------------------------------------
1683
 * String format helpers.
1684
 */
1685
1686
static PyObject *
1687
format_ctime(PyObject *date, int hours, int minutes, int seconds)
1688
0
{
1689
0
    static const char * const DayNames[] = {
1690
0
        "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1691
0
    };
1692
0
    static const char * const MonthNames[] = {
1693
0
        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1694
0
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1695
0
    };
1696
1697
0
    int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
1698
1699
0
    return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1700
0
                                DayNames[wday], MonthNames[GET_MONTH(date)-1],
1701
0
                                GET_DAY(date), hours, minutes, seconds,
1702
0
                                GET_YEAR(date));
1703
0
}
1704
1705
static PyObject *delta_negative(PyObject *op);
1706
1707
/* Add formatted UTC offset string to buf.  buf has no more than
1708
 * buflen bytes remaining.  The UTC offset is gotten by calling
1709
 * tzinfo.uctoffset(tzinfoarg).  If that returns None, \0 is stored into
1710
 * *buf, and that's all.  Else the returned value is checked for sanity (an
1711
 * integer in range), and if that's OK it's converted to an hours & minutes
1712
 * string of the form
1713
 *   sign HH sep MM [sep SS [. UUUUUU]]
1714
 * Returns 0 if everything is OK.  If the return value from utcoffset() is
1715
 * bogus, an appropriate exception is set and -1 is returned.
1716
 */
1717
static int
1718
format_utcoffset(char *buf, size_t buflen, const char *sep,
1719
                PyObject *tzinfo, PyObject *tzinfoarg)
1720
0
{
1721
0
    PyObject *offset;
1722
0
    int hours, minutes, seconds, microseconds;
1723
0
    char sign;
1724
1725
0
    assert(buflen >= 1);
1726
1727
0
    offset = call_utcoffset(tzinfo, tzinfoarg);
1728
0
    if (offset == NULL)
1729
0
        return -1;
1730
0
    if (offset == Py_None) {
1731
0
        Py_DECREF(offset);
1732
0
        *buf = '\0';
1733
0
        return 0;
1734
0
    }
1735
    /* Offset is normalized, so it is negative if days < 0 */
1736
0
    if (GET_TD_DAYS(offset) < 0) {
1737
0
        sign = '-';
1738
0
        Py_SETREF(offset, delta_negative(offset));
1739
0
        if (offset == NULL)
1740
0
            return -1;
1741
0
    }
1742
0
    else {
1743
0
        sign = '+';
1744
0
    }
1745
    /* Offset is not negative here. */
1746
0
    microseconds = GET_TD_MICROSECONDS(offset);
1747
0
    seconds = GET_TD_SECONDS(offset);
1748
0
    Py_DECREF(offset);
1749
0
    minutes = divmod(seconds, 60, &seconds);
1750
0
    hours = divmod(minutes, 60, &minutes);
1751
0
    if (microseconds) {
1752
0
        PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign,
1753
0
                      hours, sep, minutes, sep, seconds, microseconds);
1754
0
        return 0;
1755
0
    }
1756
0
    if (seconds) {
1757
0
        PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1758
0
                      sep, minutes, sep, seconds);
1759
0
        return 0;
1760
0
    }
1761
0
    PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1762
0
    return 0;
1763
0
}
1764
1765
/* Check whether year with century should be normalized for strftime. */
1766
inline static int
1767
normalize_century(void)
1768
192
{
1769
192
    static int cache = -1;
1770
192
    if (cache < 0) {
1771
4
        char year[5];
1772
4
        struct tm date = {
1773
4
            .tm_year = -1801,
1774
4
            .tm_mon = 0,
1775
4
            .tm_mday = 1
1776
4
        };
1777
4
        cache = (strftime(year, sizeof(year), "%Y", &date) &&
1778
4
                 strcmp(year, "0099") != 0);
1779
4
    }
1780
192
    return cache;
1781
192
}
1782
1783
static PyObject *
1784
make_somezreplacement(PyObject *object, char *sep, PyObject *tzinfoarg)
1785
0
{
1786
0
    char buf[100];
1787
0
    PyObject *tzinfo = get_tzinfo_member(object);
1788
1789
0
    if (tzinfo == Py_None || tzinfo == NULL) {
1790
0
        return PyUnicode_FromStringAndSize(NULL, 0);
1791
0
    }
1792
1793
0
    assert(tzinfoarg != NULL);
1794
0
    if (format_utcoffset(buf,
1795
0
                         sizeof(buf),
1796
0
                         sep,
1797
0
                         tzinfo,
1798
0
                         tzinfoarg) < 0)
1799
0
        return NULL;
1800
1801
0
    return PyUnicode_FromString(buf);
1802
0
}
1803
1804
static PyObject *
1805
make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1806
0
{
1807
0
    PyObject *temp;
1808
0
    PyObject *tzinfo = get_tzinfo_member(object);
1809
0
    PyObject *Zreplacement = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
1810
1811
0
    if (Zreplacement == NULL)
1812
0
        return NULL;
1813
0
    if (tzinfo == Py_None || tzinfo == NULL)
1814
0
        return Zreplacement;
1815
1816
0
    assert(tzinfoarg != NULL);
1817
0
    temp = call_tzname(tzinfo, tzinfoarg);
1818
0
    if (temp == NULL)
1819
0
        goto Error;
1820
0
    if (temp == Py_None) {
1821
0
        Py_DECREF(temp);
1822
0
        return Zreplacement;
1823
0
    }
1824
1825
0
    assert(PyUnicode_Check(temp));
1826
    /* Since the tzname is getting stuffed into the
1827
     * format, we have to double any % signs so that
1828
     * strftime doesn't treat them as format codes.
1829
     */
1830
0
    Py_DECREF(Zreplacement);
1831
0
    Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1832
0
    Py_DECREF(temp);
1833
0
    if (Zreplacement == NULL)
1834
0
        return NULL;
1835
0
    if (!PyUnicode_Check(Zreplacement)) {
1836
0
        PyErr_SetString(PyExc_TypeError,
1837
0
                        "tzname.replace() did not return a string");
1838
0
        goto Error;
1839
0
    }
1840
0
    return Zreplacement;
1841
1842
0
  Error:
1843
0
    Py_DECREF(Zreplacement);
1844
0
    return NULL;
1845
0
}
1846
1847
static PyObject *
1848
make_freplacement(PyObject *object)
1849
0
{
1850
0
    char freplacement[64];
1851
0
    if (PyTime_Check(object))
1852
0
        sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1853
0
    else if (PyDateTime_Check(object))
1854
0
        sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1855
0
    else
1856
0
        sprintf(freplacement, "%06d", 0);
1857
1858
0
    return PyUnicode_FromString(freplacement);
1859
0
}
1860
1861
/* I sure don't want to reproduce the strftime code from the time module,
1862
 * so this imports the module and calls it.  All the hair is due to
1863
 * giving special meanings to the %z, %:z, %Z and %f format codes via a
1864
 * preprocessing step on the format string.
1865
 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1866
 * needed.
1867
 */
1868
static PyObject *
1869
wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
1870
              PyObject *tzinfoarg)
1871
192
{
1872
192
    PyObject *result = NULL;            /* guilty until proved innocent */
1873
1874
192
    PyObject *zreplacement = NULL;      /* py string, replacement for %z */
1875
192
    PyObject *colonzreplacement = NULL; /* py string, replacement for %:z */
1876
192
    PyObject *Zreplacement = NULL;      /* py string, replacement for %Z */
1877
192
    PyObject *freplacement = NULL;      /* py string, replacement for %f */
1878
1879
192
    assert(object && format && timetuple);
1880
192
    assert(PyUnicode_Check(format));
1881
1882
192
    PyObject *strftime = PyImport_ImportModuleAttrString("time", "strftime");
1883
192
    if (strftime == NULL) {
1884
0
        return NULL;
1885
0
    }
1886
1887
    /* Scan the input format, looking for %z/%Z/%f escapes, building
1888
     * a new format.  Since computing the replacements for those codes
1889
     * is expensive, don't unless they're actually used.
1890
     */
1891
1892
192
    PyUnicodeWriter *writer = PyUnicodeWriter_Create(0);
1893
192
    if (writer == NULL) {
1894
0
        goto Error;
1895
0
    }
1896
1897
192
    Py_ssize_t flen = PyUnicode_GET_LENGTH(format);
1898
192
    Py_ssize_t i = 0;
1899
192
    Py_ssize_t start = 0;
1900
192
    Py_ssize_t end = 0;
1901
384
    while (i != flen) {
1902
288
        i = PyUnicode_FindChar(format, '%', i, flen, 1);
1903
288
        if (i < 0) {
1904
96
            assert(!PyErr_Occurred());
1905
96
            break;
1906
96
        }
1907
192
        end = i;
1908
192
        i++;
1909
192
        if (i == flen) {
1910
0
            break;
1911
0
        }
1912
192
        Py_UCS4 ch = PyUnicode_READ_CHAR(format, i);
1913
192
        i++;
1914
        /* A % has been seen and ch is the character after it. */
1915
192
        PyObject *replacement = NULL;
1916
192
        if (ch == 'z') {
1917
            /* %z -> +HHMM */
1918
0
            if (zreplacement == NULL) {
1919
0
                zreplacement = make_somezreplacement(object, "", tzinfoarg);
1920
0
                if (zreplacement == NULL)
1921
0
                    goto Error;
1922
0
            }
1923
0
            replacement = zreplacement;
1924
0
        }
1925
192
        else if (ch == ':' && i < flen && PyUnicode_READ_CHAR(format, i) == 'z') {
1926
            /* %:z -> +HH:MM */
1927
0
            i++;
1928
0
            if (colonzreplacement == NULL) {
1929
0
                colonzreplacement = make_somezreplacement(object, ":", tzinfoarg);
1930
0
                if (colonzreplacement == NULL)
1931
0
                    goto Error;
1932
0
            }
1933
0
            replacement = colonzreplacement;
1934
0
        }
1935
192
        else if (ch == 'Z') {
1936
            /* format tzname */
1937
0
            if (Zreplacement == NULL) {
1938
0
                Zreplacement = make_Zreplacement(object,
1939
0
                                                 tzinfoarg);
1940
0
                if (Zreplacement == NULL)
1941
0
                    goto Error;
1942
0
            }
1943
0
            replacement = Zreplacement;
1944
0
        }
1945
192
        else if (ch == 'f') {
1946
            /* format microseconds */
1947
0
            if (freplacement == NULL) {
1948
0
                freplacement = make_freplacement(object);
1949
0
                if (freplacement == NULL)
1950
0
                    goto Error;
1951
0
            }
1952
0
            replacement = freplacement;
1953
0
        }
1954
192
        else if (normalize_century()
1955
192
                 && (ch == 'Y' || ch == 'G' || ch == 'F' || ch == 'C'))
1956
0
        {
1957
            /* 0-pad year with century as necessary */
1958
0
            PyObject *item = PySequence_GetItem(timetuple, 0);
1959
0
            if (item == NULL) {
1960
0
                goto Error;
1961
0
            }
1962
0
            long year_long = PyLong_AsLong(item);
1963
0
            Py_DECREF(item);
1964
0
            if (year_long == -1 && PyErr_Occurred()) {
1965
0
                goto Error;
1966
0
            }
1967
            /* Note that datetime(1000, 1, 1).strftime('%G') == '1000' so year
1968
               1000 for %G can go on the fast path. */
1969
0
            if (year_long >= 1000) {
1970
0
                continue;
1971
0
            }
1972
0
            if (ch == 'G') {
1973
0
                PyObject *year_str = PyObject_CallFunction(strftime, "sO",
1974
0
                                                           "%G", timetuple);
1975
0
                if (year_str == NULL) {
1976
0
                    goto Error;
1977
0
                }
1978
0
                PyObject *year = PyNumber_Long(year_str);
1979
0
                Py_DECREF(year_str);
1980
0
                if (year == NULL) {
1981
0
                    goto Error;
1982
0
                }
1983
0
                year_long = PyLong_AsLong(year);
1984
0
                Py_DECREF(year);
1985
0
                if (year_long == -1 && PyErr_Occurred()) {
1986
0
                    goto Error;
1987
0
                }
1988
0
            }
1989
            /* Buffer of maximum size of formatted year permitted by long.
1990
             * +6 to accommodate dashes, 2-digit month and day for %F. */
1991
0
            char buf[SIZEOF_LONG * 5 / 2 + 2 + 6];
1992
0
            Py_ssize_t n = PyOS_snprintf(buf, sizeof(buf),
1993
0
                                      ch == 'F' ? "%04ld-%%m-%%d" :
1994
0
                                      "%04ld", year_long);
1995
0
            if (ch == 'C') {
1996
0
                n -= 2;
1997
0
            }
1998
0
            if (PyUnicodeWriter_WriteSubstring(writer, format, start, end) < 0) {
1999
0
                goto Error;
2000
0
            }
2001
0
            start = i;
2002
0
            if (PyUnicodeWriter_WriteUTF8(writer, buf, n) < 0) {
2003
0
                goto Error;
2004
0
            }
2005
0
            continue;
2006
0
        }
2007
192
        else {
2008
            /* percent followed by something else */
2009
192
            continue;
2010
192
        }
2011
192
        assert(replacement != NULL);
2012
0
        assert(PyUnicode_Check(replacement));
2013
0
        if (PyUnicodeWriter_WriteSubstring(writer, format, start, end) < 0) {
2014
0
            goto Error;
2015
0
        }
2016
0
        start = i;
2017
0
        if (PyUnicodeWriter_WriteStr(writer, replacement) < 0) {
2018
0
            goto Error;
2019
0
        }
2020
0
    }  /* end while() */
2021
2022
192
    PyObject *newformat;
2023
192
    if (start == 0) {
2024
192
        PyUnicodeWriter_Discard(writer);
2025
192
        newformat = Py_NewRef(format);
2026
192
    }
2027
0
    else {
2028
0
        if (PyUnicodeWriter_WriteSubstring(writer, format, start, flen) < 0) {
2029
0
            goto Error;
2030
0
        }
2031
0
        newformat = PyUnicodeWriter_Finish(writer);
2032
0
        if (newformat == NULL) {
2033
0
            goto Done;
2034
0
        }
2035
0
    }
2036
192
    result = PyObject_CallFunctionObjArgs(strftime,
2037
192
                                          newformat, timetuple, NULL);
2038
192
    Py_DECREF(newformat);
2039
2040
192
 Done:
2041
192
    Py_XDECREF(freplacement);
2042
192
    Py_XDECREF(zreplacement);
2043
192
    Py_XDECREF(colonzreplacement);
2044
192
    Py_XDECREF(Zreplacement);
2045
192
    Py_XDECREF(strftime);
2046
192
    return result;
2047
2048
0
 Error:
2049
0
    PyUnicodeWriter_Discard(writer);
2050
0
    goto Done;
2051
192
}
2052
2053
/* ---------------------------------------------------------------------------
2054
 * Wrap functions from the time module.  These aren't directly available
2055
 * from C.  Perhaps they should be.
2056
 */
2057
2058
/* Call time.time() and return its result (a Python float). */
2059
static PyObject *
2060
time_time(void)
2061
0
{
2062
0
    PyObject *result = NULL;
2063
0
    PyObject *time = PyImport_ImportModuleAttrString("time", "time");
2064
2065
0
    if (time != NULL) {
2066
0
        result = PyObject_CallNoArgs(time);
2067
0
        Py_DECREF(time);
2068
0
    }
2069
0
    return result;
2070
0
}
2071
2072
/* Build a time.struct_time.  The weekday and day number are automatically
2073
 * computed from the y,m,d args.
2074
 */
2075
static PyObject *
2076
build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
2077
10.9k
{
2078
10.9k
    PyObject *struct_time;
2079
10.9k
    PyObject *result;
2080
2081
10.9k
    struct_time = PyImport_ImportModuleAttrString("time", "struct_time");
2082
10.9k
    if (struct_time == NULL) {
2083
0
        return NULL;
2084
0
    }
2085
2086
10.9k
    result = PyObject_CallFunction(struct_time, "((iiiiiiiii))",
2087
10.9k
                         y, m, d,
2088
10.9k
                         hh, mm, ss,
2089
10.9k
                         weekday(y, m, d),
2090
10.9k
                         days_before_month(y, m) + d,
2091
10.9k
                         dstflag);
2092
10.9k
    Py_DECREF(struct_time);
2093
10.9k
    return result;
2094
10.9k
}
2095
2096
/* ---------------------------------------------------------------------------
2097
 * Miscellaneous helpers.
2098
 */
2099
2100
/* The comparisons here all most naturally compute a cmp()-like result.
2101
 * This little helper turns that into a bool result for rich comparisons.
2102
 */
2103
static PyObject *
2104
diff_to_bool(int diff, int op)
2105
9
{
2106
9
    Py_RETURN_RICHCOMPARE(diff, 0, op);
2107
9
}
2108
2109
/* ---------------------------------------------------------------------------
2110
 * Class implementations.
2111
 */
2112
2113
/*
2114
 * PyDateTime_Delta implementation.
2115
 */
2116
2117
/* Convert a timedelta to a number of us,
2118
 *      (24*3600*self.days + self.seconds)*1000000 + self.microseconds
2119
 * as a Python int.
2120
 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
2121
 * due to ubiquitous overflow possibilities.
2122
 */
2123
static PyObject *
2124
delta_to_microseconds(PyDateTime_Delta *self)
2125
82
{
2126
82
    PyObject *x1 = NULL;
2127
82
    PyObject *x2 = NULL;
2128
82
    PyObject *x3 = NULL;
2129
82
    PyObject *result = NULL;
2130
2131
82
    PyObject *current_mod = NULL;
2132
82
    datetime_state *st = GET_CURRENT_STATE(current_mod);
2133
2134
82
    x1 = PyLong_FromLong(GET_TD_DAYS(self));
2135
82
    if (x1 == NULL)
2136
0
        goto Done;
2137
82
    x2 = PyNumber_Multiply(x1, CONST_SEC_PER_DAY(st));        /* days in seconds */
2138
82
    if (x2 == NULL)
2139
0
        goto Done;
2140
82
    Py_SETREF(x1, NULL);
2141
2142
    /* x2 has days in seconds */
2143
82
    x1 = PyLong_FromLong(GET_TD_SECONDS(self));         /* seconds */
2144
82
    if (x1 == NULL)
2145
0
        goto Done;
2146
82
    x3 = PyNumber_Add(x1, x2);          /* days and seconds in seconds */
2147
82
    if (x3 == NULL)
2148
0
        goto Done;
2149
82
    Py_DECREF(x1);
2150
82
    Py_DECREF(x2);
2151
82
    /* x1 = */ x2 = NULL;
2152
2153
    /* x3 has days+seconds in seconds */
2154
82
    x1 = PyNumber_Multiply(x3, CONST_US_PER_SECOND(st));          /* us */
2155
82
    if (x1 == NULL)
2156
0
        goto Done;
2157
82
    Py_SETREF(x3, NULL);
2158
2159
    /* x1 has days+seconds in us */
2160
82
    x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
2161
82
    if (x2 == NULL)
2162
0
        goto Done;
2163
82
    result = PyNumber_Add(x1, x2);
2164
82
    assert(result == NULL || PyLong_CheckExact(result));
2165
2166
82
Done:
2167
82
    Py_XDECREF(x1);
2168
82
    Py_XDECREF(x2);
2169
82
    Py_XDECREF(x3);
2170
82
    RELEASE_CURRENT_STATE(st, current_mod);
2171
82
    return result;
2172
82
}
2173
2174
static PyObject *
2175
checked_divmod(PyObject *a, PyObject *b)
2176
21.7k
{
2177
21.7k
    PyObject *result = PyNumber_Divmod(a, b);
2178
21.7k
    if (result != NULL) {
2179
21.7k
        if (!PyTuple_Check(result)) {
2180
0
            PyErr_Format(PyExc_TypeError,
2181
0
                         "divmod() returned non-tuple (type %.200s)",
2182
0
                         Py_TYPE(result)->tp_name);
2183
0
            Py_DECREF(result);
2184
0
            return NULL;
2185
0
        }
2186
21.7k
        if (PyTuple_GET_SIZE(result) != 2) {
2187
0
            PyErr_Format(PyExc_TypeError,
2188
0
                         "divmod() returned a tuple of size %zd",
2189
0
                         PyTuple_GET_SIZE(result));
2190
0
            Py_DECREF(result);
2191
0
            return NULL;
2192
0
        }
2193
21.7k
    }
2194
21.7k
    return result;
2195
21.7k
}
2196
2197
/* Convert a number of us (as a Python int) to a timedelta.
2198
 */
2199
static PyObject *
2200
microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
2201
10.8k
{
2202
10.8k
    int us;
2203
10.8k
    int s;
2204
10.8k
    int d;
2205
2206
10.8k
    PyObject *tuple = NULL;
2207
10.8k
    PyObject *num = NULL;
2208
10.8k
    PyObject *result = NULL;
2209
2210
10.8k
    PyObject *current_mod = NULL;
2211
10.8k
    datetime_state *st = GET_CURRENT_STATE(current_mod);
2212
2213
10.8k
    tuple = checked_divmod(pyus, CONST_US_PER_SECOND(st));
2214
10.8k
    if (tuple == NULL) {
2215
0
        goto Done;
2216
0
    }
2217
2218
10.8k
    num = PyTuple_GET_ITEM(tuple, 1);           /* us */
2219
10.8k
    us = PyLong_AsInt(num);
2220
10.8k
    num = NULL;
2221
10.8k
    if (us == -1 && PyErr_Occurred()) {
2222
0
        goto Done;
2223
0
    }
2224
10.8k
    if (!(0 <= us && us < 1000000)) {
2225
0
        goto BadDivmod;
2226
0
    }
2227
2228
10.8k
    num = Py_NewRef(PyTuple_GET_ITEM(tuple, 0));        /* leftover seconds */
2229
10.8k
    Py_DECREF(tuple);
2230
2231
10.8k
    tuple = checked_divmod(num, CONST_SEC_PER_DAY(st));
2232
10.8k
    if (tuple == NULL)
2233
0
        goto Done;
2234
10.8k
    Py_DECREF(num);
2235
2236
10.8k
    num = PyTuple_GET_ITEM(tuple, 1);           /* seconds */
2237
10.8k
    s = PyLong_AsInt(num);
2238
10.8k
    num = NULL;
2239
10.8k
    if (s == -1 && PyErr_Occurred()) {
2240
0
        goto Done;
2241
0
    }
2242
10.8k
    if (!(0 <= s && s < 24*3600)) {
2243
0
        goto BadDivmod;
2244
0
    }
2245
2246
10.8k
    num = Py_NewRef(PyTuple_GET_ITEM(tuple, 0));           /* leftover days */
2247
10.8k
    d = PyLong_AsInt(num);
2248
10.8k
    if (d == -1 && PyErr_Occurred()) {
2249
5
        goto Done;
2250
5
    }
2251
10.8k
    result = new_delta_ex(d, s, us, 0, type);
2252
2253
10.8k
Done:
2254
10.8k
    Py_XDECREF(tuple);
2255
10.8k
    Py_XDECREF(num);
2256
10.8k
    RELEASE_CURRENT_STATE(st, current_mod);
2257
10.8k
    return result;
2258
2259
0
BadDivmod:
2260
0
    PyErr_SetString(PyExc_TypeError,
2261
0
                    "divmod() returned a value out of range");
2262
0
    goto Done;
2263
10.8k
}
2264
2265
#define microseconds_to_delta(pymicros) \
2266
32
    microseconds_to_delta_ex(pymicros, DELTA_TYPE(NO_STATE))
2267
2268
static PyObject *
2269
multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
2270
32
{
2271
32
    PyObject *pyus_in;
2272
32
    PyObject *pyus_out;
2273
32
    PyObject *result;
2274
2275
32
    pyus_in = delta_to_microseconds(delta);
2276
32
    if (pyus_in == NULL)
2277
0
        return NULL;
2278
2279
32
    pyus_out = PyNumber_Multiply(intobj, pyus_in);
2280
32
    Py_DECREF(pyus_in);
2281
32
    if (pyus_out == NULL)
2282
0
        return NULL;
2283
2284
32
    result = microseconds_to_delta(pyus_out);
2285
32
    Py_DECREF(pyus_out);
2286
32
    return result;
2287
32
}
2288
2289
static PyObject *
2290
get_float_as_integer_ratio(PyObject *floatobj)
2291
0
{
2292
0
    PyObject *ratio;
2293
2294
0
    assert(floatobj && PyFloat_Check(floatobj));
2295
0
    ratio = PyObject_CallMethodNoArgs(floatobj, &_Py_ID(as_integer_ratio));
2296
0
    if (ratio == NULL) {
2297
0
        return NULL;
2298
0
    }
2299
0
    if (!PyTuple_Check(ratio)) {
2300
0
        PyErr_Format(PyExc_TypeError,
2301
0
                     "unexpected return type from as_integer_ratio(): "
2302
0
                     "expected tuple, not '%.200s'",
2303
0
                     Py_TYPE(ratio)->tp_name);
2304
0
        Py_DECREF(ratio);
2305
0
        return NULL;
2306
0
    }
2307
0
    if (PyTuple_Size(ratio) != 2) {
2308
0
        PyErr_SetString(PyExc_ValueError,
2309
0
                        "as_integer_ratio() must return a 2-tuple");
2310
0
        Py_DECREF(ratio);
2311
0
        return NULL;
2312
0
    }
2313
0
    return ratio;
2314
0
}
2315
2316
/* op is 0 for multiplication, 1 for division */
2317
static PyObject *
2318
multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
2319
0
{
2320
0
    PyObject *result = NULL;
2321
0
    PyObject *pyus_in = NULL, *temp, *pyus_out;
2322
0
    PyObject *ratio = NULL;
2323
2324
0
    pyus_in = delta_to_microseconds(delta);
2325
0
    if (pyus_in == NULL)
2326
0
        return NULL;
2327
0
    ratio = get_float_as_integer_ratio(floatobj);
2328
0
    if (ratio == NULL) {
2329
0
        goto error;
2330
0
    }
2331
0
    temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
2332
0
    Py_SETREF(pyus_in, NULL);
2333
0
    if (temp == NULL)
2334
0
        goto error;
2335
0
    pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
2336
0
    Py_DECREF(temp);
2337
0
    if (pyus_out == NULL)
2338
0
        goto error;
2339
0
    result = microseconds_to_delta(pyus_out);
2340
0
    Py_DECREF(pyus_out);
2341
0
 error:
2342
0
    Py_XDECREF(pyus_in);
2343
0
    Py_XDECREF(ratio);
2344
2345
0
    return result;
2346
0
}
2347
2348
static PyObject *
2349
divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
2350
0
{
2351
0
    PyObject *pyus_in;
2352
0
    PyObject *pyus_out;
2353
0
    PyObject *result;
2354
2355
0
    pyus_in = delta_to_microseconds(delta);
2356
0
    if (pyus_in == NULL)
2357
0
        return NULL;
2358
2359
0
    pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
2360
0
    Py_DECREF(pyus_in);
2361
0
    if (pyus_out == NULL)
2362
0
        return NULL;
2363
2364
0
    result = microseconds_to_delta(pyus_out);
2365
0
    Py_DECREF(pyus_out);
2366
0
    return result;
2367
0
}
2368
2369
static PyObject *
2370
divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2371
0
{
2372
0
    PyObject *pyus_left;
2373
0
    PyObject *pyus_right;
2374
0
    PyObject *result;
2375
2376
0
    pyus_left = delta_to_microseconds(left);
2377
0
    if (pyus_left == NULL)
2378
0
        return NULL;
2379
2380
0
    pyus_right = delta_to_microseconds(right);
2381
0
    if (pyus_right == NULL)     {
2382
0
        Py_DECREF(pyus_left);
2383
0
        return NULL;
2384
0
    }
2385
2386
0
    result = PyNumber_FloorDivide(pyus_left, pyus_right);
2387
0
    Py_DECREF(pyus_left);
2388
0
    Py_DECREF(pyus_right);
2389
0
    return result;
2390
0
}
2391
2392
static PyObject *
2393
truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2394
0
{
2395
0
    PyObject *pyus_left;
2396
0
    PyObject *pyus_right;
2397
0
    PyObject *result;
2398
2399
0
    pyus_left = delta_to_microseconds(left);
2400
0
    if (pyus_left == NULL)
2401
0
        return NULL;
2402
2403
0
    pyus_right = delta_to_microseconds(right);
2404
0
    if (pyus_right == NULL)     {
2405
0
        Py_DECREF(pyus_left);
2406
0
        return NULL;
2407
0
    }
2408
2409
0
    result = PyNumber_TrueDivide(pyus_left, pyus_right);
2410
0
    Py_DECREF(pyus_left);
2411
0
    Py_DECREF(pyus_right);
2412
0
    return result;
2413
0
}
2414
2415
static PyObject *
2416
truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2417
0
{
2418
0
    PyObject *result;
2419
0
    PyObject *pyus_in, *pyus_out;
2420
0
    pyus_in = delta_to_microseconds(delta);
2421
0
    if (pyus_in == NULL)
2422
0
        return NULL;
2423
0
    pyus_out = divide_nearest(pyus_in, i);
2424
0
    Py_DECREF(pyus_in);
2425
0
    if (pyus_out == NULL)
2426
0
        return NULL;
2427
0
    result = microseconds_to_delta(pyus_out);
2428
0
    Py_DECREF(pyus_out);
2429
2430
0
    return result;
2431
0
}
2432
2433
static PyObject *
2434
delta_add(PyObject *left, PyObject *right)
2435
0
{
2436
0
    PyObject *result = Py_NotImplemented;
2437
2438
0
    if (PyDelta_Check(left) && PyDelta_Check(right)) {
2439
        /* delta + delta */
2440
        /* The C-level additions can't overflow because of the
2441
         * invariant bounds.
2442
         */
2443
0
        int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2444
0
        int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2445
0
        int microseconds = GET_TD_MICROSECONDS(left) +
2446
0
                           GET_TD_MICROSECONDS(right);
2447
0
        result = new_delta(days, seconds, microseconds, 1);
2448
0
    }
2449
2450
0
    if (result == Py_NotImplemented)
2451
0
        Py_INCREF(result);
2452
0
    return result;
2453
0
}
2454
2455
static PyObject *
2456
delta_negative(PyObject *self)
2457
0
{
2458
0
    return new_delta(-GET_TD_DAYS(self),
2459
0
                     -GET_TD_SECONDS(self),
2460
0
                     -GET_TD_MICROSECONDS(self),
2461
0
                     1);
2462
0
}
2463
2464
static PyObject *
2465
delta_positive(PyObject *self)
2466
0
{
2467
    /* Could optimize this (by returning self) if this isn't a
2468
     * subclass -- but who uses unary + ?  Approximately nobody.
2469
     */
2470
0
    return new_delta(GET_TD_DAYS(self),
2471
0
                     GET_TD_SECONDS(self),
2472
0
                     GET_TD_MICROSECONDS(self),
2473
0
                     0);
2474
0
}
2475
2476
static PyObject *
2477
delta_abs(PyObject *self)
2478
0
{
2479
0
    PyObject *result;
2480
2481
0
    assert(GET_TD_MICROSECONDS(self) >= 0);
2482
0
    assert(GET_TD_SECONDS(self) >= 0);
2483
2484
0
    if (GET_TD_DAYS(self) < 0)
2485
0
        result = delta_negative(self);
2486
0
    else
2487
0
        result = delta_positive(self);
2488
2489
0
    return result;
2490
0
}
2491
2492
static PyObject *
2493
delta_subtract(PyObject *left, PyObject *right)
2494
0
{
2495
0
    PyObject *result = Py_NotImplemented;
2496
2497
0
    if (PyDelta_Check(left) && PyDelta_Check(right)) {
2498
        /* delta - delta */
2499
        /* The C-level additions can't overflow because of the
2500
         * invariant bounds.
2501
         */
2502
0
        int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2503
0
        int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2504
0
        int microseconds = GET_TD_MICROSECONDS(left) -
2505
0
                           GET_TD_MICROSECONDS(right);
2506
0
        result = new_delta(days, seconds, microseconds, 1);
2507
0
    }
2508
2509
0
    if (result == Py_NotImplemented)
2510
0
        Py_INCREF(result);
2511
0
    return result;
2512
0
}
2513
2514
static int
2515
delta_cmp(PyObject *self, PyObject *other)
2516
9
{
2517
9
    int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2518
9
    if (diff == 0) {
2519
5
        diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2520
5
        if (diff == 0)
2521
4
            diff = GET_TD_MICROSECONDS(self) -
2522
4
                GET_TD_MICROSECONDS(other);
2523
5
    }
2524
9
    return diff;
2525
9
}
2526
2527
static PyObject *
2528
delta_richcompare(PyObject *self, PyObject *other, int op)
2529
9
{
2530
9
    if (PyDelta_Check(other)) {
2531
9
        int diff = delta_cmp(self, other);
2532
9
        return diff_to_bool(diff, op);
2533
9
    }
2534
0
    else {
2535
0
        Py_RETURN_NOTIMPLEMENTED;
2536
0
    }
2537
9
}
2538
2539
static PyObject *delta_getstate(PyDateTime_Delta *self);
2540
2541
static Py_hash_t
2542
delta_hash(PyObject *op)
2543
0
{
2544
0
    PyDateTime_Delta *self = PyDelta_CAST(op);
2545
0
    Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
2546
0
    if (hash == -1) {
2547
0
        PyObject *temp = delta_getstate(self);
2548
0
        if (temp != NULL) {
2549
0
            hash = PyObject_Hash(temp);
2550
0
            FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
2551
0
            Py_DECREF(temp);
2552
0
        }
2553
0
    }
2554
0
    return hash;
2555
0
}
2556
2557
static PyObject *
2558
delta_multiply(PyObject *left, PyObject *right)
2559
32
{
2560
32
    PyObject *result = Py_NotImplemented;
2561
2562
32
    if (PyDelta_Check(left)) {
2563
        /* delta * ??? */
2564
0
        if (PyLong_Check(right))
2565
0
            result = multiply_int_timedelta(right,
2566
0
                            (PyDateTime_Delta *) left);
2567
0
        else if (PyFloat_Check(right))
2568
0
            result = multiply_truedivide_timedelta_float(
2569
0
                            (PyDateTime_Delta *) left, right, 0);
2570
0
    }
2571
32
    else if (PyLong_Check(left))
2572
32
        result = multiply_int_timedelta(left,
2573
32
                        (PyDateTime_Delta *) right);
2574
0
    else if (PyFloat_Check(left))
2575
0
        result = multiply_truedivide_timedelta_float(
2576
0
                        (PyDateTime_Delta *) right, left, 0);
2577
2578
32
    if (result == Py_NotImplemented)
2579
0
        Py_INCREF(result);
2580
32
    return result;
2581
32
}
2582
2583
static PyObject *
2584
delta_divide(PyObject *left, PyObject *right)
2585
0
{
2586
0
    PyObject *result = Py_NotImplemented;
2587
2588
0
    if (PyDelta_Check(left)) {
2589
        /* delta * ??? */
2590
0
        if (PyLong_Check(right))
2591
0
            result = divide_timedelta_int(
2592
0
                            (PyDateTime_Delta *)left,
2593
0
                            right);
2594
0
        else if (PyDelta_Check(right))
2595
0
            result = divide_timedelta_timedelta(
2596
0
                            (PyDateTime_Delta *)left,
2597
0
                            (PyDateTime_Delta *)right);
2598
0
    }
2599
2600
0
    if (result == Py_NotImplemented)
2601
0
        Py_INCREF(result);
2602
0
    return result;
2603
0
}
2604
2605
static PyObject *
2606
delta_truedivide(PyObject *left, PyObject *right)
2607
0
{
2608
0
    PyObject *result = Py_NotImplemented;
2609
2610
0
    if (PyDelta_Check(left)) {
2611
0
        if (PyDelta_Check(right))
2612
0
            result = truedivide_timedelta_timedelta(
2613
0
                            (PyDateTime_Delta *)left,
2614
0
                            (PyDateTime_Delta *)right);
2615
0
        else if (PyFloat_Check(right))
2616
0
            result = multiply_truedivide_timedelta_float(
2617
0
                            (PyDateTime_Delta *)left, right, 1);
2618
0
        else if (PyLong_Check(right))
2619
0
            result = truedivide_timedelta_int(
2620
0
                            (PyDateTime_Delta *)left, right);
2621
0
    }
2622
2623
0
    if (result == Py_NotImplemented)
2624
0
        Py_INCREF(result);
2625
0
    return result;
2626
0
}
2627
2628
static PyObject *
2629
delta_remainder(PyObject *left, PyObject *right)
2630
0
{
2631
0
    PyObject *pyus_left;
2632
0
    PyObject *pyus_right;
2633
0
    PyObject *pyus_remainder;
2634
0
    PyObject *remainder;
2635
2636
0
    if (!PyDelta_Check(left) || !PyDelta_Check(right))
2637
0
        Py_RETURN_NOTIMPLEMENTED;
2638
2639
0
    pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2640
0
    if (pyus_left == NULL)
2641
0
        return NULL;
2642
2643
0
    pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2644
0
    if (pyus_right == NULL) {
2645
0
        Py_DECREF(pyus_left);
2646
0
        return NULL;
2647
0
    }
2648
2649
0
    pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2650
0
    Py_DECREF(pyus_left);
2651
0
    Py_DECREF(pyus_right);
2652
0
    if (pyus_remainder == NULL)
2653
0
        return NULL;
2654
2655
0
    remainder = microseconds_to_delta(pyus_remainder);
2656
0
    Py_DECREF(pyus_remainder);
2657
0
    if (remainder == NULL)
2658
0
        return NULL;
2659
2660
0
    return remainder;
2661
0
}
2662
2663
static PyObject *
2664
delta_divmod(PyObject *left, PyObject *right)
2665
0
{
2666
0
    PyObject *pyus_left;
2667
0
    PyObject *pyus_right;
2668
0
    PyObject *divmod;
2669
0
    PyObject *delta;
2670
0
    PyObject *result;
2671
2672
0
    if (!PyDelta_Check(left) || !PyDelta_Check(right))
2673
0
        Py_RETURN_NOTIMPLEMENTED;
2674
2675
0
    pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2676
0
    if (pyus_left == NULL)
2677
0
        return NULL;
2678
2679
0
    pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2680
0
    if (pyus_right == NULL) {
2681
0
        Py_DECREF(pyus_left);
2682
0
        return NULL;
2683
0
    }
2684
2685
0
    divmod = checked_divmod(pyus_left, pyus_right);
2686
0
    Py_DECREF(pyus_left);
2687
0
    Py_DECREF(pyus_right);
2688
0
    if (divmod == NULL)
2689
0
        return NULL;
2690
2691
0
    delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2692
0
    if (delta == NULL) {
2693
0
        Py_DECREF(divmod);
2694
0
        return NULL;
2695
0
    }
2696
0
    result = _PyTuple_FromPair(PyTuple_GET_ITEM(divmod, 0), delta);
2697
0
    Py_DECREF(delta);
2698
0
    Py_DECREF(divmod);
2699
0
    return result;
2700
0
}
2701
2702
/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2703
 * timedelta constructor.  sofar is the # of microseconds accounted for
2704
 * so far, and there are factor microseconds per current unit, the number
2705
 * of which is given by num.  num * factor is added to sofar in a
2706
 * numerically careful way, and that's the result.  Any fractional
2707
 * microseconds left over (this can happen if num is a float type) are
2708
 * added into *leftover.
2709
 * Note that there are many ways this can give an error (NULL) return.
2710
 */
2711
static PyObject *
2712
accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2713
      double *leftover)
2714
10.8k
{
2715
10.8k
    PyObject *prod;
2716
10.8k
    PyObject *sum;
2717
2718
10.8k
    assert(num != NULL);
2719
2720
10.8k
    if (PyLong_Check(num)) {
2721
10.8k
        prod = PyNumber_Multiply(num, factor);
2722
10.8k
        if (prod == NULL)
2723
0
            return NULL;
2724
10.8k
        sum = PyNumber_Add(sofar, prod);
2725
10.8k
        Py_DECREF(prod);
2726
10.8k
        return sum;
2727
10.8k
    }
2728
2729
17
    if (PyFloat_Check(num)) {
2730
17
        double dnum;
2731
17
        double fracpart;
2732
17
        double intpart;
2733
17
        PyObject *x;
2734
17
        PyObject *y;
2735
2736
        /* The Plan:  decompose num into an integer part and a
2737
         * fractional part, num = intpart + fracpart.
2738
         * Then num * factor ==
2739
         *      intpart * factor + fracpart * factor
2740
         * and the LHS can be computed exactly in long arithmetic.
2741
         * The RHS is again broken into an int part and frac part.
2742
         * and the frac part is added into *leftover.
2743
         */
2744
17
        dnum = PyFloat_AsDouble(num);
2745
17
        if (dnum == -1.0 && PyErr_Occurred())
2746
0
            return NULL;
2747
17
        fracpart = modf(dnum, &intpart);
2748
17
        x = PyLong_FromDouble(intpart);
2749
17
        if (x == NULL)
2750
0
            return NULL;
2751
2752
17
        prod = PyNumber_Multiply(x, factor);
2753
17
        Py_DECREF(x);
2754
17
        if (prod == NULL)
2755
0
            return NULL;
2756
2757
17
        sum = PyNumber_Add(sofar, prod);
2758
17
        Py_DECREF(prod);
2759
17
        if (sum == NULL)
2760
0
            return NULL;
2761
2762
17
        if (fracpart == 0.0)
2763
5
            return sum;
2764
        /* So far we've lost no information.  Dealing with the
2765
         * fractional part requires float arithmetic, and may
2766
         * lose a little info.
2767
         */
2768
17
        assert(PyLong_CheckExact(factor));
2769
12
        dnum = PyLong_AsDouble(factor);
2770
2771
12
        dnum *= fracpart;
2772
12
        fracpart = modf(dnum, &intpart);
2773
12
        x = PyLong_FromDouble(intpart);
2774
12
        if (x == NULL) {
2775
0
            Py_DECREF(sum);
2776
0
            return NULL;
2777
0
        }
2778
2779
12
        y = PyNumber_Add(sum, x);
2780
12
        Py_DECREF(sum);
2781
12
        Py_DECREF(x);
2782
12
        *leftover += fracpart;
2783
12
        return y;
2784
12
    }
2785
2786
0
    PyErr_Format(PyExc_TypeError,
2787
0
                 "unsupported type for timedelta %s component: %s",
2788
0
                 tag, Py_TYPE(num)->tp_name);
2789
0
    return NULL;
2790
17
}
2791
2792
/*[clinic input]
2793
@classmethod
2794
datetime.timedelta.__new__ as delta_new
2795
2796
    days: object(c_default="NULL") = 0
2797
    seconds: object(c_default="NULL") = 0
2798
    microseconds: object(c_default="NULL") = 0
2799
    milliseconds: object(c_default="NULL") = 0
2800
    minutes: object(c_default="NULL") = 0
2801
    hours: object(c_default="NULL") = 0
2802
    weeks: object(c_default="NULL") = 0
2803
2804
Difference between two datetime values.
2805
2806
All arguments are optional and default to 0.
2807
Arguments may be integers or floats, and may be positive or negative.
2808
[clinic start generated code]*/
2809
2810
static PyObject *
2811
delta_new_impl(PyTypeObject *type, PyObject *days, PyObject *seconds,
2812
               PyObject *microseconds, PyObject *milliseconds,
2813
               PyObject *minutes, PyObject *hours, PyObject *weeks)
2814
/*[clinic end generated code: output=61d7e02a92a97700 input=e8cd54819295d34b]*/
2815
10.8k
{
2816
10.8k
    PyObject *self = NULL;
2817
2818
10.8k
    PyObject *current_mod = NULL;
2819
10.8k
    datetime_state *st = GET_CURRENT_STATE(current_mod);
2820
2821
10.8k
    PyObject *x = NULL;         /* running sum of microseconds */
2822
10.8k
    PyObject *y = NULL;         /* temp sum of microseconds */
2823
10.8k
    double leftover_us = 0.0;
2824
2825
10.8k
    x = PyLong_FromLong(0);
2826
10.8k
    if (x == NULL)
2827
0
        goto Done;
2828
2829
10.8k
#define CLEANUP         \
2830
10.8k
    Py_DECREF(x);       \
2831
10.8k
    x = y;              \
2832
10.8k
    if (x == NULL)      \
2833
10.8k
        goto Done
2834
2835
10.8k
    if (microseconds) {
2836
0
        y = accum("microseconds", x, microseconds, _PyLong_GetOne(), &leftover_us);
2837
0
        CLEANUP;
2838
0
    }
2839
10.8k
    if (milliseconds) {
2840
4
        y = accum("milliseconds", x, milliseconds, CONST_US_PER_MS(st), &leftover_us);
2841
4
        CLEANUP;
2842
4
    }
2843
10.8k
    if (seconds) {
2844
10.8k
        y = accum("seconds", x, seconds, CONST_US_PER_SECOND(st), &leftover_us);
2845
10.8k
        CLEANUP;
2846
10.8k
    }
2847
10.8k
    if (minutes) {
2848
4
        y = accum("minutes", x, minutes, CONST_US_PER_MINUTE(st), &leftover_us);
2849
4
        CLEANUP;
2850
4
    }
2851
10.8k
    if (hours) {
2852
4
        y = accum("hours", x, hours, CONST_US_PER_HOUR(st), &leftover_us);
2853
4
        CLEANUP;
2854
4
    }
2855
10.8k
    if (days) {
2856
8
        y = accum("days", x, days, CONST_US_PER_DAY(st), &leftover_us);
2857
8
        CLEANUP;
2858
8
    }
2859
10.8k
    if (weeks) {
2860
0
        y = accum("weeks", x, weeks, CONST_US_PER_WEEK(st), &leftover_us);
2861
0
        CLEANUP;
2862
0
    }
2863
10.8k
    if (leftover_us) {
2864
        /* Round to nearest whole # of us, and add into x. */
2865
8
        double whole_us = round(leftover_us);
2866
8
        int x_is_odd;
2867
8
        PyObject *temp;
2868
2869
8
        if (fabs(whole_us - leftover_us) == 0.5) {
2870
            /* We're exactly halfway between two integers.  In order
2871
             * to do round-half-to-even, we must determine whether x
2872
             * is odd. Note that x is odd when it's last bit is 1. The
2873
             * code below uses bitwise and operation to check the last
2874
             * bit. */
2875
0
            temp = PyNumber_And(x, _PyLong_GetOne());  /* temp <- x & 1 */
2876
0
            if (temp == NULL) {
2877
0
                Py_DECREF(x);
2878
0
                goto Done;
2879
0
            }
2880
0
            x_is_odd = PyObject_IsTrue(temp);
2881
0
            Py_DECREF(temp);
2882
0
            if (x_is_odd == -1) {
2883
0
                Py_DECREF(x);
2884
0
                goto Done;
2885
0
            }
2886
0
            whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2887
0
        }
2888
2889
8
        temp = PyLong_FromLong((long)whole_us);
2890
2891
8
        if (temp == NULL) {
2892
0
            Py_DECREF(x);
2893
0
            goto Done;
2894
0
        }
2895
8
        y = PyNumber_Add(x, temp);
2896
8
        Py_DECREF(temp);
2897
8
        CLEANUP;
2898
8
    }
2899
2900
10.8k
    self = microseconds_to_delta_ex(x, type);
2901
10.8k
    Py_DECREF(x);
2902
2903
10.8k
Done:
2904
10.8k
    RELEASE_CURRENT_STATE(st, current_mod);
2905
10.8k
    return self;
2906
2907
10.8k
#undef CLEANUP
2908
10.8k
}
2909
2910
static int
2911
delta_bool(PyObject *self)
2912
770
{
2913
770
    return (GET_TD_DAYS(self) != 0
2914
710
        || GET_TD_SECONDS(self) != 0
2915
338
        || GET_TD_MICROSECONDS(self) != 0);
2916
770
}
2917
2918
static PyObject *
2919
delta_repr(PyObject *self)
2920
0
{
2921
0
    PyObject *args = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
2922
2923
0
    if (args == NULL) {
2924
0
        return NULL;
2925
0
    }
2926
2927
0
    const char *sep = "";
2928
2929
0
    if (GET_TD_DAYS(self) != 0) {
2930
0
        Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2931
0
        if (args == NULL) {
2932
0
            return NULL;
2933
0
        }
2934
0
        sep = ", ";
2935
0
    }
2936
2937
0
    if (GET_TD_SECONDS(self) != 0) {
2938
0
        Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2939
0
                                             GET_TD_SECONDS(self)));
2940
0
        if (args == NULL) {
2941
0
            return NULL;
2942
0
        }
2943
0
        sep = ", ";
2944
0
    }
2945
2946
0
    if (GET_TD_MICROSECONDS(self) != 0) {
2947
0
        Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2948
0
                                             GET_TD_MICROSECONDS(self)));
2949
0
        if (args == NULL) {
2950
0
            return NULL;
2951
0
        }
2952
0
    }
2953
2954
0
    if (PyUnicode_GET_LENGTH(args) == 0) {
2955
0
        Py_SETREF(args, PyUnicode_FromString("0"));
2956
0
        if (args == NULL) {
2957
0
            return NULL;
2958
0
        }
2959
0
    }
2960
2961
0
    PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2962
0
                                          args);
2963
0
    Py_DECREF(args);
2964
0
    return repr;
2965
0
}
2966
2967
static PyObject *
2968
delta_str(PyObject *self)
2969
0
{
2970
0
    int us = GET_TD_MICROSECONDS(self);
2971
0
    int seconds = GET_TD_SECONDS(self);
2972
0
    int minutes = divmod(seconds, 60, &seconds);
2973
0
    int hours = divmod(minutes, 60, &minutes);
2974
0
    int days = GET_TD_DAYS(self);
2975
2976
0
    if (days) {
2977
0
        if (us)
2978
0
            return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2979
0
                                        days, (days == 1 || days == -1) ? "" : "s",
2980
0
                                        hours, minutes, seconds, us);
2981
0
        else
2982
0
            return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2983
0
                                        days, (days == 1 || days == -1) ? "" : "s",
2984
0
                                        hours, minutes, seconds);
2985
0
    } else {
2986
0
        if (us)
2987
0
            return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2988
0
                                        hours, minutes, seconds, us);
2989
0
        else
2990
0
            return PyUnicode_FromFormat("%d:%02d:%02d",
2991
0
                                        hours, minutes, seconds);
2992
0
    }
2993
2994
0
}
2995
2996
/* Pickle support, a simple use of __reduce__. */
2997
2998
/* __getstate__ isn't exposed */
2999
static PyObject *
3000
delta_getstate(PyDateTime_Delta *self)
3001
0
{
3002
0
    return Py_BuildValue("iii", GET_TD_DAYS(self),
3003
0
                                GET_TD_SECONDS(self),
3004
0
                                GET_TD_MICROSECONDS(self));
3005
0
}
3006
3007
static PyObject *
3008
delta_total_seconds(PyObject *op, PyObject *Py_UNUSED(dummy))
3009
50
{
3010
50
    PyObject *total_seconds;
3011
50
    PyObject *total_microseconds;
3012
3013
50
    total_microseconds = delta_to_microseconds(PyDelta_CAST(op));
3014
50
    if (total_microseconds == NULL)
3015
0
        return NULL;
3016
3017
50
    PyObject *current_mod = NULL;
3018
50
    datetime_state *st = GET_CURRENT_STATE(current_mod);
3019
3020
50
    total_seconds = PyNumber_TrueDivide(total_microseconds, CONST_US_PER_SECOND(st));
3021
3022
50
    RELEASE_CURRENT_STATE(st, current_mod);
3023
50
    Py_DECREF(total_microseconds);
3024
50
    return total_seconds;
3025
50
}
3026
3027
static PyObject *
3028
delta_reduce(PyObject *op, PyObject *Py_UNUSED(dummy))
3029
0
{
3030
0
    PyDateTime_Delta *self = PyDelta_CAST(op);
3031
0
    return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
3032
0
}
3033
3034
#define OFFSET(field)  offsetof(PyDateTime_Delta, field)
3035
3036
static PyMemberDef delta_members[] = {
3037
3038
    {"days",         Py_T_INT, OFFSET(days),         Py_READONLY,
3039
     PyDoc_STR("Number of days.")},
3040
3041
    {"seconds",      Py_T_INT, OFFSET(seconds),      Py_READONLY,
3042
     PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
3043
3044
    {"microseconds", Py_T_INT, OFFSET(microseconds), Py_READONLY,
3045
     PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
3046
    {NULL}
3047
};
3048
3049
static PyMethodDef delta_methods[] = {
3050
    {"total_seconds", delta_total_seconds, METH_NOARGS,
3051
     PyDoc_STR("Total seconds in the duration.")},
3052
3053
    {"__reduce__", delta_reduce, METH_NOARGS,
3054
     PyDoc_STR("__reduce__() -> (cls, state)")},
3055
3056
    {NULL,      NULL},
3057
};
3058
3059
static PyNumberMethods delta_as_number = {
3060
    delta_add,                                  /* nb_add */
3061
    delta_subtract,                             /* nb_subtract */
3062
    delta_multiply,                             /* nb_multiply */
3063
    delta_remainder,                            /* nb_remainder */
3064
    delta_divmod,                               /* nb_divmod */
3065
    0,                                          /* nb_power */
3066
    delta_negative,                             /* nb_negative */
3067
    delta_positive,                             /* nb_positive */
3068
    delta_abs,                                  /* nb_absolute */
3069
    delta_bool,                                 /* nb_bool */
3070
    0,                                          /*nb_invert*/
3071
    0,                                          /*nb_lshift*/
3072
    0,                                          /*nb_rshift*/
3073
    0,                                          /*nb_and*/
3074
    0,                                          /*nb_xor*/
3075
    0,                                          /*nb_or*/
3076
    0,                                          /*nb_int*/
3077
    0,                                          /*nb_reserved*/
3078
    0,                                          /*nb_float*/
3079
    0,                                          /*nb_inplace_add*/
3080
    0,                                          /*nb_inplace_subtract*/
3081
    0,                                          /*nb_inplace_multiply*/
3082
    0,                                          /*nb_inplace_remainder*/
3083
    0,                                          /*nb_inplace_power*/
3084
    0,                                          /*nb_inplace_lshift*/
3085
    0,                                          /*nb_inplace_rshift*/
3086
    0,                                          /*nb_inplace_and*/
3087
    0,                                          /*nb_inplace_xor*/
3088
    0,                                          /*nb_inplace_or*/
3089
    delta_divide,                               /* nb_floor_divide */
3090
    delta_truedivide,                           /* nb_true_divide */
3091
    0,                                          /* nb_inplace_floor_divide */
3092
    0,                                          /* nb_inplace_true_divide */
3093
};
3094
3095
static PyTypeObject PyDateTime_DeltaType = {
3096
    PyVarObject_HEAD_INIT(NULL, 0)
3097
    "datetime.timedelta",                               /* tp_name */
3098
    sizeof(PyDateTime_Delta),                           /* tp_basicsize */
3099
    0,                                                  /* tp_itemsize */
3100
    0,                                                  /* tp_dealloc */
3101
    0,                                                  /* tp_vectorcall_offset */
3102
    0,                                                  /* tp_getattr */
3103
    0,                                                  /* tp_setattr */
3104
    0,                                                  /* tp_as_async */
3105
    delta_repr,                                         /* tp_repr */
3106
    &delta_as_number,                                   /* tp_as_number */
3107
    0,                                                  /* tp_as_sequence */
3108
    0,                                                  /* tp_as_mapping */
3109
    delta_hash,                                         /* tp_hash */
3110
    0,                                                  /* tp_call */
3111
    delta_str,                                          /* tp_str */
3112
    PyObject_GenericGetAttr,                            /* tp_getattro */
3113
    0,                                                  /* tp_setattro */
3114
    0,                                                  /* tp_as_buffer */
3115
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,           /* tp_flags */
3116
    delta_new__doc__,                                   /* tp_doc */
3117
    0,                                                  /* tp_traverse */
3118
    0,                                                  /* tp_clear */
3119
    delta_richcompare,                                  /* tp_richcompare */
3120
    0,                                                  /* tp_weaklistoffset */
3121
    0,                                                  /* tp_iter */
3122
    0,                                                  /* tp_iternext */
3123
    delta_methods,                                      /* tp_methods */
3124
    delta_members,                                      /* tp_members */
3125
    0,                                                  /* tp_getset */
3126
    0,                                                  /* tp_base */
3127
    0,                                                  /* tp_dict */
3128
    0,                                                  /* tp_descr_get */
3129
    0,                                                  /* tp_descr_set */
3130
    0,                                                  /* tp_dictoffset */
3131
    0,                                                  /* tp_init */
3132
    0,                                                  /* tp_alloc */
3133
    delta_new,                                          /* tp_new */
3134
    0,                                                  /* tp_free */
3135
};
3136
3137
// XXX Can we make this const?
3138
static PyDateTime_Delta zero_delta = {
3139
    PyObject_HEAD_INIT(&PyDateTime_DeltaType)
3140
    /* Letting this be set lazily is a benign race. */
3141
    .hashcode = -1,
3142
};
3143
3144
static PyDateTime_Delta *
3145
look_up_delta(int days, int seconds, int microseconds, PyTypeObject *type)
3146
21.5k
{
3147
21.5k
    if (days == 0 && seconds == 0 && microseconds == 0
3148
997
            && type == Py_TYPE(&zero_delta))
3149
997
    {
3150
997
        return &zero_delta;
3151
997
    }
3152
20.5k
    return NULL;
3153
21.5k
}
3154
3155
3156
/*
3157
 * PyDateTime_Date implementation.
3158
 */
3159
3160
/* Accessor properties. */
3161
3162
static PyObject *
3163
date_year(PyObject *op, void *Py_UNUSED(closure))
3164
8
{
3165
8
    PyDateTime_Date *self = PyDate_CAST(op);
3166
8
    return PyLong_FromLong(GET_YEAR(self));
3167
8
}
3168
3169
static PyObject *
3170
date_month(PyObject *op, void *Py_UNUSED(closure))
3171
8
{
3172
8
    PyDateTime_Date *self = PyDate_CAST(op);
3173
8
    return PyLong_FromLong(GET_MONTH(self));
3174
8
}
3175
3176
static PyObject *
3177
date_day(PyObject *op, void *Py_UNUSED(closure))
3178
8
{
3179
8
    PyDateTime_Date *self = PyDate_CAST(op);
3180
8
    return PyLong_FromLong(GET_DAY(self));
3181
8
}
3182
3183
static PyGetSetDef date_getset[] = {
3184
    {"year", date_year},
3185
    {"month", date_month},
3186
    {"day", date_day},
3187
    {NULL}
3188
};
3189
3190
/* Constructors. */
3191
3192
static PyObject *
3193
date_from_pickle(PyTypeObject *type, PyObject *state)
3194
0
{
3195
0
    PyDateTime_Date *me;
3196
3197
0
    me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
3198
0
    if (me != NULL) {
3199
0
        const char *pdata = PyBytes_AS_STRING(state);
3200
0
        memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
3201
0
        me->hashcode = -1;
3202
0
    }
3203
0
    return (PyObject *)me;
3204
0
}
3205
3206
static PyObject *
3207
date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3208
194
{
3209
    /* Check for invocation from pickle with __getstate__ state */
3210
194
    if (PyTuple_GET_SIZE(args) == 1) {
3211
0
        PyObject *state = PyTuple_GET_ITEM(args, 0);
3212
0
        if (PyBytes_Check(state)) {
3213
0
            if (PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
3214
0
                MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
3215
0
            {
3216
0
                return date_from_pickle(type, state);
3217
0
            }
3218
0
        }
3219
0
        else if (PyUnicode_Check(state)) {
3220
0
            if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATE_DATASIZE &&
3221
0
                MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2)))
3222
0
            {
3223
0
                state = PyUnicode_AsLatin1String(state);
3224
0
                if (state == NULL) {
3225
0
                    if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
3226
                        /* More informative error message. */
3227
0
                        PyErr_SetString(PyExc_ValueError,
3228
0
                            "Failed to encode latin1 string when unpickling "
3229
0
                            "a date object. "
3230
0
                            "pickle.load(data, encoding='latin1') is assumed.");
3231
0
                    }
3232
0
                    return NULL;
3233
0
                }
3234
0
                PyObject *self = date_from_pickle(type, state);
3235
0
                Py_DECREF(state);
3236
0
                return self;
3237
0
            }
3238
0
        }
3239
0
    }
3240
3241
194
    return datetime_date(type, args, kw);
3242
194
}
3243
3244
/*[clinic input]
3245
@classmethod
3246
datetime.date.__new__
3247
3248
    year: int
3249
    month: int
3250
    day: int
3251
3252
Concrete date type.
3253
[clinic start generated code]*/
3254
3255
static PyObject *
3256
datetime_date_impl(PyTypeObject *type, int year, int month, int day)
3257
/*[clinic end generated code: output=6654caa3dea7d518 input=fd1bac0658690455]*/
3258
194
{
3259
194
    return new_date_ex(year, month, day, type);
3260
194
}
3261
3262
static PyObject *
3263
date_fromtimestamp(PyTypeObject *cls, PyObject *obj)
3264
0
{
3265
0
    struct tm tm;
3266
0
    time_t t;
3267
3268
0
    if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
3269
0
        return NULL;
3270
3271
0
    if (_PyTime_localtime(t, &tm) != 0)
3272
0
        return NULL;
3273
3274
0
    return new_date_subclass_ex(tm.tm_year + 1900,
3275
0
                                tm.tm_mon + 1,
3276
0
                                tm.tm_mday,
3277
0
                                cls);
3278
0
}
3279
3280
/* Return new date from current time.
3281
 * We say this is equivalent to fromtimestamp(time.time()), and the
3282
 * only way to be sure of that is to *call* time.time().  That's not
3283
 * generally the same as calling C's time.
3284
 */
3285
/*[clinic input]
3286
@classmethod
3287
datetime.date.today
3288
3289
Current date or datetime.
3290
3291
Equivalent to fromtimestamp(time.time()).
3292
[clinic start generated code]*/
3293
3294
static PyObject *
3295
datetime_date_today_impl(PyTypeObject *type)
3296
/*[clinic end generated code: output=d5474697df6b251c input=21688afa289c0a06]*/
3297
0
{
3298
    /* Use C implementation to boost performance for date type */
3299
0
    if (type == &PyDateTime_DateType) {
3300
0
        struct tm tm;
3301
0
        time_t t;
3302
0
        time(&t);
3303
3304
0
        if (_PyTime_localtime(t, &tm) != 0) {
3305
0
            return NULL;
3306
0
        }
3307
3308
0
        return new_date_ex(tm.tm_year + 1900,
3309
0
                           tm.tm_mon + 1,
3310
0
                           tm.tm_mday,
3311
0
                           type);
3312
0
    }
3313
3314
0
    PyObject *time = time_time();
3315
0
    if (time == NULL) {
3316
0
        return NULL;
3317
0
    }
3318
3319
    /* Note well: since today() is a class method, it may not call
3320
     * date.fromtimestamp, e.g., it may call datetime.fromtimestamp.
3321
     */
3322
0
    PyObject *result = PyObject_CallMethodOneArg((PyObject*)type, &_Py_ID(fromtimestamp), time);
3323
0
    Py_DECREF(time);
3324
0
    return result;
3325
0
}
3326
3327
/*[clinic input]
3328
@permit_long_docstring_body
3329
@classmethod
3330
datetime.date.fromtimestamp
3331
3332
    timestamp: object
3333
    /
3334
3335
Create a date from a POSIX timestamp.
3336
3337
The timestamp is a number, e.g. created via time.time(), that is interpreted
3338
as local time.
3339
[clinic start generated code]*/
3340
3341
static PyObject *
3342
datetime_date_fromtimestamp_impl(PyTypeObject *type, PyObject *timestamp)
3343
/*[clinic end generated code: output=59def4e32c028fb6 input=55ff6940f0a8339f]*/
3344
0
{
3345
0
    return date_fromtimestamp(type, timestamp);
3346
0
}
3347
3348
/* bpo-36025: This is a wrapper for API compatibility with the public C API,
3349
 * which expects a function that takes an *args tuple, whereas the argument
3350
 * clinic generates code that takes METH_O.
3351
 */
3352
static PyObject *
3353
datetime_date_fromtimestamp_capi(PyObject *cls, PyObject *args)
3354
0
{
3355
0
    PyObject *timestamp;
3356
0
    PyObject *result = NULL;
3357
3358
0
    if (PyArg_UnpackTuple(args, "fromtimestamp", 1, 1, &timestamp)) {
3359
0
        result = date_fromtimestamp((PyTypeObject *)cls, timestamp);
3360
0
    }
3361
3362
0
    return result;
3363
0
}
3364
3365
/*[clinic input]
3366
@classmethod
3367
datetime.date.fromordinal
3368
3369
    ordinal: int
3370
    /
3371
3372
Construct a date from a proleptic Gregorian ordinal.
3373
3374
January 1 of year 1 is day 1.  Only the year, month and day are
3375
non-zero in the result.
3376
[clinic start generated code]*/
3377
3378
static PyObject *
3379
datetime_date_fromordinal_impl(PyTypeObject *type, int ordinal)
3380
/*[clinic end generated code: output=ea5cc69d86614a6b input=a3a4eedf582f145e]*/
3381
0
{
3382
0
    int year;
3383
0
    int month;
3384
0
    int day;
3385
3386
0
    if (ordinal < 1) {
3387
0
        PyErr_SetString(PyExc_ValueError, "ordinal must be >= 1");
3388
0
        return NULL;
3389
0
    }
3390
0
    ord_to_ymd(ordinal, &year, &month, &day);
3391
0
    return new_date_subclass_ex(year, month, day, type);
3392
0
}
3393
3394
/*[clinic input]
3395
@classmethod
3396
datetime.date.fromisoformat
3397
3398
    string: unicode
3399
    /
3400
3401
Construct a date from a string in ISO 8601 format.
3402
[clinic start generated code]*/
3403
3404
static PyObject *
3405
datetime_date_fromisoformat_impl(PyTypeObject *type, PyObject *string)
3406
/*[clinic end generated code: output=8b9f9324904fca02 input=73c64216c10bcc8e]*/
3407
0
{
3408
0
    Py_ssize_t len;
3409
3410
0
    const char *dt_ptr = PyUnicode_AsUTF8AndSize(string, &len);
3411
0
    if (dt_ptr == NULL) {
3412
0
        goto invalid_string_error;
3413
0
    }
3414
3415
0
    int year = 0, month = 0, day = 0;
3416
3417
0
    int rv;
3418
0
    if (len == 7 || len == 8 || len == 10) {
3419
0
        rv = parse_isoformat_date(dt_ptr, len, &year, &month, &day);
3420
0
    }
3421
0
    else {
3422
0
        rv = -1;
3423
0
    }
3424
3425
0
    if (rv < 0) {
3426
0
        goto invalid_string_error;
3427
0
    }
3428
3429
0
    return new_date_subclass_ex(year, month, day, type);
3430
3431
0
invalid_string_error:
3432
0
    PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", string);
3433
0
    return NULL;
3434
0
}
3435
3436
3437
/*[clinic input]
3438
@classmethod
3439
datetime.date.fromisocalendar
3440
3441
    year: int
3442
    week: int
3443
    day: int
3444
3445
Construct a date from the ISO year, week number and weekday.
3446
3447
This is the inverse of the date.isocalendar() function.
3448
[clinic start generated code]*/
3449
3450
static PyObject *
3451
datetime_date_fromisocalendar_impl(PyTypeObject *type, int year, int week,
3452
                                   int day)
3453
/*[clinic end generated code: output=7b26e15115d24df6 input=fbb05b53d6fb51d8]*/
3454
0
{
3455
0
    int month;
3456
0
    int rv = iso_to_ymd(year, week, day, &year, &month, &day);
3457
3458
0
    if (rv == -4) {
3459
0
        PyErr_Format(PyExc_ValueError,
3460
0
                     "year must be in %d..%d, not %d", MINYEAR, MAXYEAR, year);
3461
0
        return NULL;
3462
0
    }
3463
3464
0
    if (rv == -2) {
3465
0
        PyErr_Format(PyExc_ValueError, "Invalid week: %d", week);
3466
0
        return NULL;
3467
0
    }
3468
3469
0
    if (rv == -3) {
3470
0
        PyErr_Format(PyExc_ValueError, "Invalid weekday: %d (range is [1, 7])",
3471
0
                     day);
3472
0
        return NULL;
3473
0
    }
3474
3475
0
    return new_date_subclass_ex(year, month, day, type);
3476
0
}
3477
3478
/*[clinic input]
3479
@classmethod
3480
datetime.date.strptime
3481
3482
    string: unicode
3483
    format: unicode
3484
    /
3485
3486
Parse string according to the given date format (like time.strptime()).
3487
3488
For a list of supported format codes, see the documentation:
3489
    https://docs.python.org/3/library/datetime.html#format-codes
3490
[clinic start generated code]*/
3491
3492
static PyObject *
3493
datetime_date_strptime_impl(PyTypeObject *type, PyObject *string,
3494
                            PyObject *format)
3495
/*[clinic end generated code: output=454d473bee2d5161 input=31d57bb789433e99]*/
3496
0
{
3497
0
    PyObject *result;
3498
3499
0
    PyObject *module = PyImport_Import(&_Py_ID(_strptime));
3500
0
    if (module == NULL) {
3501
0
        return NULL;
3502
0
    }
3503
0
    result = PyObject_CallMethodObjArgs(module,
3504
0
                                        &_Py_ID(_strptime_datetime_date),
3505
0
                                        (PyObject *)type, string, format, NULL);
3506
0
    Py_DECREF(module);
3507
0
    return result;
3508
0
}
3509
3510
3511
/*
3512
 * Date arithmetic.
3513
 */
3514
3515
/* date + timedelta -> date.  If arg negate is true, subtract the timedelta
3516
 * instead.
3517
 */
3518
static PyObject *
3519
add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
3520
0
{
3521
0
    PyObject *result = NULL;
3522
0
    int year = GET_YEAR(date);
3523
0
    int month = GET_MONTH(date);
3524
0
    int deltadays = GET_TD_DAYS(delta);
3525
    /* C-level overflow is impossible because |deltadays| < 1e9. */
3526
0
    int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
3527
3528
0
    if (normalize_date(&year, &month, &day) >= 0)
3529
0
        result = new_date_subclass_ex(year, month, day, Py_TYPE(date));
3530
0
    return result;
3531
0
}
3532
3533
static PyObject *
3534
date_add(PyObject *left, PyObject *right)
3535
0
{
3536
0
    if (PyDateTime_Check(left) || PyDateTime_Check(right))
3537
0
        Py_RETURN_NOTIMPLEMENTED;
3538
3539
0
    if (PyDate_Check(left)) {
3540
        /* date + ??? */
3541
0
        if (PyDelta_Check(right))
3542
            /* date + delta */
3543
0
            return add_date_timedelta((PyDateTime_Date *) left,
3544
0
                                      (PyDateTime_Delta *) right,
3545
0
                                      0);
3546
0
    }
3547
0
    else {
3548
        /* ??? + date
3549
         * 'right' must be one of us, or we wouldn't have been called
3550
         */
3551
0
        if (PyDelta_Check(left))
3552
            /* delta + date */
3553
0
            return add_date_timedelta((PyDateTime_Date *) right,
3554
0
                                      (PyDateTime_Delta *) left,
3555
0
                                      0);
3556
0
    }
3557
0
    Py_RETURN_NOTIMPLEMENTED;
3558
0
}
3559
3560
static PyObject *
3561
date_subtract(PyObject *left, PyObject *right)
3562
0
{
3563
0
    if (PyDateTime_Check(left) || PyDateTime_Check(right))
3564
0
        Py_RETURN_NOTIMPLEMENTED;
3565
3566
0
    if (PyDate_Check(left)) {
3567
0
        if (PyDate_Check(right)) {
3568
            /* date - date */
3569
0
            int left_ord = ymd_to_ord(GET_YEAR(left),
3570
0
                                      GET_MONTH(left),
3571
0
                                      GET_DAY(left));
3572
0
            int right_ord = ymd_to_ord(GET_YEAR(right),
3573
0
                                       GET_MONTH(right),
3574
0
                                       GET_DAY(right));
3575
0
            return new_delta(left_ord - right_ord, 0, 0, 0);
3576
0
        }
3577
0
        if (PyDelta_Check(right)) {
3578
            /* date - delta */
3579
0
            return add_date_timedelta((PyDateTime_Date *) left,
3580
0
                                      (PyDateTime_Delta *) right,
3581
0
                                      1);
3582
0
        }
3583
0
    }
3584
0
    Py_RETURN_NOTIMPLEMENTED;
3585
0
}
3586
3587
3588
/* Various ways to turn a date into a string. */
3589
3590
static PyObject *
3591
date_repr(PyObject *op)
3592
0
{
3593
0
    PyDateTime_Date *self = PyDate_CAST(op);
3594
0
    return PyUnicode_FromFormat("%s(%d, %d, %d)",
3595
0
                                Py_TYPE(self)->tp_name,
3596
0
                                GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
3597
0
}
3598
3599
static PyObject *
3600
date_isoformat(PyObject *op, PyObject *Py_UNUSED(dummy))
3601
0
{
3602
0
    PyDateTime_Date *self = PyDate_CAST(op);
3603
0
    return PyUnicode_FromFormat("%04d-%02d-%02d",
3604
0
                                GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
3605
0
}
3606
3607
/* str() calls the appropriate isoformat() method. */
3608
static PyObject *
3609
date_str(PyObject *self)
3610
0
{
3611
0
    return PyObject_CallMethodNoArgs(self, &_Py_ID(isoformat));
3612
0
}
3613
3614
3615
static PyObject *
3616
date_ctime(PyObject *self, PyObject *Py_UNUSED(dummy))
3617
0
{
3618
0
    return format_ctime(self, 0, 0, 0);
3619
0
}
3620
3621
/*[clinic input]
3622
datetime.date.strftime
3623
3624
    self: self(type="PyObject *")
3625
    format: unicode
3626
3627
Format using strftime().
3628
3629
Example: "%d/%m/%Y, %H:%M:%S".
3630
3631
For a list of supported format codes, see the documentation:
3632
    https://docs.python.org/3/library/datetime.html#format-codes
3633
[clinic start generated code]*/
3634
3635
static PyObject *
3636
datetime_date_strftime_impl(PyObject *self, PyObject *format)
3637
/*[clinic end generated code: output=6529b70095e16778 input=b6fd4a2ded27b557]*/
3638
192
{
3639
    /* This method can be inherited, and needs to call the
3640
     * timetuple() method appropriate to self's class.
3641
     */
3642
192
    PyObject *result;
3643
192
    PyObject *tuple;
3644
3645
192
    tuple = PyObject_CallMethodNoArgs(self, &_Py_ID(timetuple));
3646
192
    if (tuple == NULL)
3647
0
        return NULL;
3648
192
    result = wrap_strftime(self, format, tuple, self);
3649
192
    Py_DECREF(tuple);
3650
192
    return result;
3651
192
}
3652
3653
/*[clinic input]
3654
datetime.date.__format__
3655
3656
    self: self(type="PyObject *")
3657
    format: unicode
3658
    /
3659
3660
Formats self with strftime.
3661
[clinic start generated code]*/
3662
3663
static PyObject *
3664
datetime_date___format___impl(PyObject *self, PyObject *format)
3665
/*[clinic end generated code: output=efa0223d000a93b7 input=e417a7c84e1abaf9]*/
3666
0
{
3667
    /* if the format is zero length, return str(self) */
3668
0
    if (PyUnicode_GetLength(format) == 0)
3669
0
        return PyObject_Str(self);
3670
3671
0
    return PyObject_CallMethodOneArg(self, &_Py_ID(strftime), format);
3672
0
}
3673
3674
/* ISO methods. */
3675
3676
static PyObject *
3677
date_isoweekday(PyObject *self, PyObject *Py_UNUSED(dummy))
3678
0
{
3679
0
    int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
3680
3681
0
    return PyLong_FromLong(dow + 1);
3682
0
}
3683
3684
PyDoc_STRVAR(iso_calendar_date__doc__,
3685
"The result of date.isocalendar() or datetime.isocalendar()\n\n\
3686
This object may be accessed either as a tuple of\n\
3687
  ((year, week, weekday)\n\
3688
or via the object attributes as named in the above tuple.");
3689
3690
typedef struct {
3691
    PyTupleObject tuple;
3692
} PyDateTime_IsoCalendarDate;
3693
3694
static PyObject *
3695
iso_calendar_date_repr(PyObject *self)
3696
0
{
3697
0
    PyObject *year = PyTuple_GetItem(self, 0);
3698
0
    if (year == NULL) {
3699
0
        return NULL;
3700
0
    }
3701
0
    PyObject *week = PyTuple_GetItem(self, 1);
3702
0
    if (week == NULL) {
3703
0
        return NULL;
3704
0
    }
3705
0
    PyObject *weekday = PyTuple_GetItem(self, 2);
3706
0
    if (weekday == NULL) {
3707
0
        return NULL;
3708
0
    }
3709
3710
0
    return PyUnicode_FromFormat("%.200s(year=%S, week=%S, weekday=%S)",
3711
0
                               Py_TYPE(self)->tp_name, year, week, weekday);
3712
0
}
3713
3714
static PyObject *
3715
iso_calendar_date_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
3716
0
{
3717
    // Construct the tuple that this reduces to
3718
0
    PyObject *reduce_tuple = Py_BuildValue(
3719
0
        "O((OOO))", &PyTuple_Type,
3720
0
        PyTuple_GET_ITEM(self, 0),
3721
0
        PyTuple_GET_ITEM(self, 1),
3722
0
        PyTuple_GET_ITEM(self, 2)
3723
0
    );
3724
3725
0
    return reduce_tuple;
3726
0
}
3727
3728
static PyObject *
3729
iso_calendar_date_year(PyObject *self, void *Py_UNUSED(closure))
3730
0
{
3731
0
    PyObject *year = PyTuple_GetItem(self, 0);
3732
0
    if (year == NULL) {
3733
0
        return NULL;
3734
0
    }
3735
0
    return Py_NewRef(year);
3736
0
}
3737
3738
static PyObject *
3739
iso_calendar_date_week(PyObject *self, void *Py_UNUSED(closure))
3740
0
{
3741
0
    PyObject *week = PyTuple_GetItem(self, 1);
3742
0
    if (week == NULL) {
3743
0
        return NULL;
3744
0
    }
3745
0
    return Py_NewRef(week);
3746
0
}
3747
3748
static PyObject *
3749
iso_calendar_date_weekday(PyObject *self, void *Py_UNUSED(closure))
3750
0
{
3751
0
    PyObject *weekday = PyTuple_GetItem(self, 2);
3752
0
    if (weekday == NULL) {
3753
0
        return NULL;
3754
0
    }
3755
0
    return Py_NewRef(weekday);
3756
0
}
3757
3758
static PyGetSetDef iso_calendar_date_getset[] = {
3759
    {"year", iso_calendar_date_year},
3760
    {"week", iso_calendar_date_week},
3761
    {"weekday", iso_calendar_date_weekday},
3762
    {NULL}
3763
};
3764
3765
static PyMethodDef iso_calendar_date_methods[] = {
3766
    {"__reduce__", iso_calendar_date_reduce, METH_NOARGS,
3767
     PyDoc_STR("__reduce__() -> (cls, state)")},
3768
    {NULL, NULL},
3769
};
3770
3771
static int
3772
iso_calendar_date_traverse(PyObject *self, visitproc visit, void *arg)
3773
0
{
3774
0
    Py_VISIT(Py_TYPE(self));
3775
0
    return PyTuple_Type.tp_traverse(self, visit, arg);
3776
0
}
3777
3778
static void
3779
iso_calendar_date_dealloc(PyObject *self)
3780
0
{
3781
0
    PyTypeObject *tp = Py_TYPE(self);
3782
0
    PyTuple_Type.tp_dealloc(self);  // delegate GC-untrack as well
3783
0
    Py_DECREF(tp);
3784
0
}
3785
3786
static PyType_Slot isocal_slots[] = {
3787
    {Py_tp_repr, iso_calendar_date_repr},
3788
    {Py_tp_doc, (void *)iso_calendar_date__doc__},
3789
    {Py_tp_methods, iso_calendar_date_methods},
3790
    {Py_tp_getset, iso_calendar_date_getset},
3791
    {Py_tp_new, iso_calendar_date_new},
3792
    {Py_tp_dealloc, iso_calendar_date_dealloc},
3793
    {Py_tp_traverse, iso_calendar_date_traverse},
3794
    {0, NULL},
3795
};
3796
3797
static PyType_Spec isocal_spec = {
3798
    .name = "datetime.IsoCalendarDate",
3799
    .basicsize = sizeof(PyDateTime_IsoCalendarDate),
3800
    .flags = (Py_TPFLAGS_DEFAULT |
3801
              Py_TPFLAGS_HAVE_GC |
3802
              Py_TPFLAGS_IMMUTABLETYPE),
3803
    .slots = isocal_slots,
3804
};
3805
3806
/*[clinic input]
3807
@classmethod
3808
datetime.IsoCalendarDate.__new__ as iso_calendar_date_new
3809
    year: int
3810
    week: int
3811
    weekday: int
3812
[clinic start generated code]*/
3813
3814
static PyObject *
3815
iso_calendar_date_new_impl(PyTypeObject *type, int year, int week,
3816
                           int weekday)
3817
/*[clinic end generated code: output=383d33d8dc7183a2 input=4f2c663c9d19c4ee]*/
3818
3819
0
{
3820
0
    PyDateTime_IsoCalendarDate *self;
3821
0
    self = (PyDateTime_IsoCalendarDate *) type->tp_alloc(type, 3);
3822
0
    if (self == NULL) {
3823
0
        return NULL;
3824
0
    }
3825
3826
0
    PyObject *year_object = PyLong_FromLong(year);
3827
0
    if (year_object == NULL) {
3828
0
        Py_DECREF(self);
3829
0
        return NULL;
3830
0
    }
3831
0
    PyTuple_SET_ITEM(self, 0, year_object);
3832
3833
0
    PyObject *week_object = PyLong_FromLong(week);
3834
0
    if (week_object == NULL) {
3835
0
        Py_DECREF(self);
3836
0
        return NULL;
3837
0
    }
3838
0
    PyTuple_SET_ITEM(self, 1, week_object);
3839
3840
0
    PyObject *weekday_object = PyLong_FromLong(weekday);
3841
0
    if (weekday_object == NULL) {
3842
0
        Py_DECREF(self);
3843
0
        return NULL;
3844
0
    }
3845
0
    PyTuple_SET_ITEM(self, 2, weekday_object);
3846
3847
0
    return (PyObject *)self;
3848
0
}
3849
3850
static PyObject *
3851
date_isocalendar(PyObject *self, PyObject *Py_UNUSED(dummy))
3852
0
{
3853
0
    int  year         = GET_YEAR(self);
3854
0
    int  week1_monday = iso_week1_monday(year);
3855
0
    int today         = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3856
0
    int  week;
3857
0
    int  day;
3858
3859
0
    week = divmod(today - week1_monday, 7, &day);
3860
0
    if (week < 0) {
3861
0
        --year;
3862
0
        week1_monday = iso_week1_monday(year);
3863
0
        week = divmod(today - week1_monday, 7, &day);
3864
0
    }
3865
0
    else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3866
0
        ++year;
3867
0
        week = 0;
3868
0
    }
3869
3870
0
    PyObject *current_mod = NULL;
3871
0
    datetime_state *st = GET_CURRENT_STATE(current_mod);
3872
3873
0
    PyObject *v = iso_calendar_date_new_impl(ISOCALENDAR_DATE_TYPE(st),
3874
0
                                             year, week + 1, day + 1);
3875
0
    RELEASE_CURRENT_STATE(st, current_mod);
3876
0
    if (v == NULL) {
3877
0
        return NULL;
3878
0
    }
3879
0
    return v;
3880
0
}
3881
3882
/* Miscellaneous methods. */
3883
3884
static PyObject *
3885
date_richcompare(PyObject *self, PyObject *other, int op)
3886
0
{
3887
    /* Since DateTime is a subclass of Date, if the other object is
3888
     * a DateTime, it would compute an equality testing or an ordering
3889
     * based on the date part alone, and we don't want that.
3890
     * So return NotImplemented here in that case.
3891
     * If a subclass wants to change this, it's up to the subclass to do so.
3892
     * The behavior is the same as if Date and DateTime were independent
3893
     * classes.
3894
     */
3895
0
    if (PyDate_Check(other) && !PyDateTime_Check(other)) {
3896
0
        int diff = memcmp(((PyDateTime_Date *)self)->data,
3897
0
                          ((PyDateTime_Date *)other)->data,
3898
0
                          _PyDateTime_DATE_DATASIZE);
3899
0
        return diff_to_bool(diff, op);
3900
0
    }
3901
0
    else
3902
0
        Py_RETURN_NOTIMPLEMENTED;
3903
0
}
3904
3905
static PyObject *
3906
date_timetuple(PyObject *self, PyObject *Py_UNUSED(dummy))
3907
192
{
3908
192
    return build_struct_time(GET_YEAR(self),
3909
192
                             GET_MONTH(self),
3910
192
                             GET_DAY(self),
3911
192
                             0, 0, 0, -1);
3912
192
}
3913
3914
/*[clinic input]
3915
datetime.date.replace
3916
3917
    year: int(c_default="GET_YEAR(self)") = unchanged
3918
    month: int(c_default="GET_MONTH(self)") = unchanged
3919
    day: int(c_default="GET_DAY(self)") = unchanged
3920
3921
Return date with new specified fields.
3922
[clinic start generated code]*/
3923
3924
static PyObject *
3925
datetime_date_replace_impl(PyDateTime_Date *self, int year, int month,
3926
                           int day)
3927
/*[clinic end generated code: output=2a9430d1e6318aeb input=0d1f02685b3e90f6]*/
3928
0
{
3929
0
    return new_date_subclass_ex(year, month, day, Py_TYPE(self));
3930
0
}
3931
3932
static Py_hash_t
3933
generic_hash(unsigned char *data, int len)
3934
8
{
3935
8
    return Py_HashBuffer(data, len);
3936
8
}
3937
3938
3939
static PyObject *date_getstate(PyDateTime_Date *self);
3940
3941
static Py_hash_t
3942
date_hash(PyObject *op)
3943
0
{
3944
0
    PyDateTime_Date *self = PyDate_CAST(op);
3945
0
    Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
3946
0
    if (hash == -1) {
3947
0
        hash = generic_hash(
3948
0
            (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
3949
0
        FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
3950
0
    }
3951
3952
0
    return hash;
3953
0
}
3954
3955
static PyObject *
3956
date_toordinal(PyObject *self, PyObject *Py_UNUSED(dummy))
3957
4
{
3958
4
    return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3959
4
                                      GET_DAY(self)));
3960
4
}
3961
3962
static PyObject *
3963
date_weekday(PyObject *self, PyObject *Py_UNUSED(dummy))
3964
0
{
3965
0
    int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
3966
0
    return PyLong_FromLong(dow);
3967
0
}
3968
3969
/* Pickle support, a simple use of __reduce__. */
3970
3971
/* __getstate__ isn't exposed */
3972
static PyObject *
3973
date_getstate(PyDateTime_Date *self)
3974
0
{
3975
0
    PyObject* field;
3976
0
    field = PyBytes_FromStringAndSize((char*)self->data,
3977
0
                                       _PyDateTime_DATE_DATASIZE);
3978
0
    return Py_BuildValue("(N)", field);
3979
0
}
3980
3981
static PyObject *
3982
date_reduce(PyObject *op, PyObject *Py_UNUSED(dummy))
3983
0
{
3984
0
    PyDateTime_Date *self = PyDate_CAST(op);
3985
0
    return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
3986
0
}
3987
3988
static PyMethodDef date_methods[] = {
3989
3990
    /* Class methods: */
3991
    DATETIME_DATE_FROMTIMESTAMP_METHODDEF
3992
    DATETIME_DATE_FROMORDINAL_METHODDEF
3993
    DATETIME_DATE_FROMISOFORMAT_METHODDEF
3994
    DATETIME_DATE_FROMISOCALENDAR_METHODDEF
3995
    DATETIME_DATE_STRPTIME_METHODDEF
3996
    DATETIME_DATE_TODAY_METHODDEF
3997
3998
    /* Instance methods: */
3999
4000
    {"ctime", date_ctime, METH_NOARGS,
4001
     PyDoc_STR("Return ctime() style string.")},
4002
4003
    DATETIME_DATE_STRFTIME_METHODDEF
4004
    DATETIME_DATE___FORMAT___METHODDEF
4005
4006
    {"timetuple", date_timetuple, METH_NOARGS,
4007
     PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4008
4009
    {"isocalendar", date_isocalendar,  METH_NOARGS,
4010
     PyDoc_STR("Return a named tuple containing ISO year, week number, and "
4011
               "weekday.")},
4012
4013
    {"isoformat", date_isoformat, METH_NOARGS,
4014
     PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
4015
4016
    {"isoweekday", date_isoweekday, METH_NOARGS,
4017
     PyDoc_STR("Return the day of the week represented by the date.\n"
4018
               "Monday == 1 ... Sunday == 7")},
4019
4020
    {"toordinal", date_toordinal, METH_NOARGS,
4021
     PyDoc_STR("Return proleptic Gregorian ordinal.  January 1 of year "
4022
               "1 is day 1.")},
4023
4024
    {"weekday", date_weekday, METH_NOARGS,
4025
     PyDoc_STR("Return the day of the week represented by the date.\n"
4026
               "Monday == 0 ... Sunday == 6")},
4027
4028
    DATETIME_DATE_REPLACE_METHODDEF
4029
4030
    {"__replace__", _PyCFunction_CAST(datetime_date_replace), METH_FASTCALL | METH_KEYWORDS,
4031
     PyDoc_STR("__replace__($self, /, **changes)\n--\n\nThe same as replace().")},
4032
4033
    {"__reduce__", date_reduce, METH_NOARGS,
4034
     PyDoc_STR("__reduce__() -> (cls, state)")},
4035
4036
    {NULL,      NULL}
4037
};
4038
4039
static PyNumberMethods date_as_number = {
4040
    date_add,                                           /* nb_add */
4041
    date_subtract,                                      /* nb_subtract */
4042
    0,                                                  /* nb_multiply */
4043
    0,                                                  /* nb_remainder */
4044
    0,                                                  /* nb_divmod */
4045
    0,                                                  /* nb_power */
4046
    0,                                                  /* nb_negative */
4047
    0,                                                  /* nb_positive */
4048
    0,                                                  /* nb_absolute */
4049
    0,                                                  /* nb_bool */
4050
};
4051
4052
static PyTypeObject PyDateTime_DateType = {
4053
    PyVarObject_HEAD_INIT(NULL, 0)
4054
    "datetime.date",                                    /* tp_name */
4055
    sizeof(PyDateTime_Date),                            /* tp_basicsize */
4056
    0,                                                  /* tp_itemsize */
4057
    0,                                                  /* tp_dealloc */
4058
    0,                                                  /* tp_vectorcall_offset */
4059
    0,                                                  /* tp_getattr */
4060
    0,                                                  /* tp_setattr */
4061
    0,                                                  /* tp_as_async */
4062
    date_repr,                                          /* tp_repr */
4063
    &date_as_number,                                    /* tp_as_number */
4064
    0,                                                  /* tp_as_sequence */
4065
    0,                                                  /* tp_as_mapping */
4066
    date_hash,                                          /* tp_hash */
4067
    0,                                                  /* tp_call */
4068
    date_str,                                           /* tp_str */
4069
    PyObject_GenericGetAttr,                            /* tp_getattro */
4070
    0,                                                  /* tp_setattro */
4071
    0,                                                  /* tp_as_buffer */
4072
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,           /* tp_flags */
4073
    datetime_date__doc__,                               /* tp_doc */
4074
    0,                                                  /* tp_traverse */
4075
    0,                                                  /* tp_clear */
4076
    date_richcompare,                                   /* tp_richcompare */
4077
    0,                                                  /* tp_weaklistoffset */
4078
    0,                                                  /* tp_iter */
4079
    0,                                                  /* tp_iternext */
4080
    date_methods,                                       /* tp_methods */
4081
    0,                                                  /* tp_members */
4082
    date_getset,                                        /* tp_getset */
4083
    0,                                                  /* tp_base */
4084
    0,                                                  /* tp_dict */
4085
    0,                                                  /* tp_descr_get */
4086
    0,                                                  /* tp_descr_set */
4087
    0,                                                  /* tp_dictoffset */
4088
    0,                                                  /* tp_init */
4089
    0,                                                  /* tp_alloc */
4090
    date_new,                                           /* tp_new */
4091
    0,                                                  /* tp_free */
4092
};
4093
4094
/*
4095
 * PyDateTime_TZInfo implementation.
4096
 */
4097
4098
/* This is a pure abstract base class, so doesn't do anything beyond
4099
 * raising NotImplemented exceptions.  Real tzinfo classes need
4100
 * to derive from this.  This is mostly for clarity, and for efficiency in
4101
 * datetime and time constructors (their tzinfo arguments need to
4102
 * be subclasses of this tzinfo class, which is easy and quick to check).
4103
 *
4104
 * Note:  For reasons having to do with pickling of subclasses, we have
4105
 * to allow tzinfo objects to be instantiated.  This wasn't an issue
4106
 * in the Python implementation (__init__() could raise NotImplementedError
4107
 * there without ill effect), but doing so in the C implementation hit a
4108
 * brick wall.
4109
 */
4110
4111
static PyObject *
4112
tzinfo_nogo(const char* methodname)
4113
0
{
4114
0
    PyErr_Format(PyExc_NotImplementedError,
4115
0
                 "a tzinfo subclass must implement %s()",
4116
0
                 methodname);
4117
0
    return NULL;
4118
0
}
4119
4120
/* Methods.  A subclass must implement these. */
4121
4122
static PyObject *
4123
tzinfo_tzname(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(dt))
4124
0
{
4125
0
    return tzinfo_nogo("tzname");
4126
0
}
4127
4128
static PyObject *
4129
tzinfo_utcoffset(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(dt))
4130
0
{
4131
0
    return tzinfo_nogo("utcoffset");
4132
0
}
4133
4134
static PyObject *
4135
tzinfo_dst(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(dt))
4136
0
{
4137
0
    return tzinfo_nogo("dst");
4138
0
}
4139
4140
4141
static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
4142
                                        PyDateTime_Delta *delta,
4143
                                        int factor);
4144
static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
4145
static PyObject *datetime_dst(PyObject *self, PyObject *);
4146
4147
static PyObject *
4148
tzinfo_fromutc(PyObject *self, PyObject *dt)
4149
0
{
4150
0
    PyObject *result = NULL;
4151
0
    PyObject *off = NULL, *dst = NULL;
4152
0
    PyDateTime_Delta *delta = NULL;
4153
4154
0
    if (!PyDateTime_Check(dt)) {
4155
0
        PyErr_SetString(PyExc_TypeError,
4156
0
                        "fromutc: argument must be a datetime");
4157
0
        return NULL;
4158
0
    }
4159
0
    if (GET_DT_TZINFO(dt) != self) {
4160
0
        PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
4161
0
                        "is not self");
4162
0
        return NULL;
4163
0
    }
4164
4165
0
    off = datetime_utcoffset(dt, NULL);
4166
0
    if (off == NULL)
4167
0
        return NULL;
4168
0
    if (off == Py_None) {
4169
0
        PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
4170
0
                        "utcoffset() result required");
4171
0
        goto Fail;
4172
0
    }
4173
4174
0
    dst = datetime_dst(dt, NULL);
4175
0
    if (dst == NULL)
4176
0
        goto Fail;
4177
0
    if (dst == Py_None) {
4178
0
        PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
4179
0
                        "dst() result required");
4180
0
        goto Fail;
4181
0
    }
4182
4183
0
    delta = (PyDateTime_Delta *)delta_subtract(off, dst);
4184
0
    if (delta == NULL)
4185
0
        goto Fail;
4186
0
    result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
4187
0
    if (result == NULL)
4188
0
        goto Fail;
4189
4190
0
    Py_DECREF(dst);
4191
0
    dst = call_dst(GET_DT_TZINFO(dt), result);
4192
0
    if (dst == NULL)
4193
0
        goto Fail;
4194
0
    if (dst == Py_None)
4195
0
        goto Inconsistent;
4196
0
    if (delta_bool(dst) != 0) {
4197
0
        Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
4198
0
                                                 (PyDateTime_Delta *)dst, 1));
4199
0
        if (result == NULL)
4200
0
            goto Fail;
4201
0
    }
4202
0
    Py_DECREF(delta);
4203
0
    Py_DECREF(dst);
4204
0
    Py_DECREF(off);
4205
0
    return result;
4206
4207
0
Inconsistent:
4208
0
    PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
4209
0
                    "inconsistent results; cannot convert");
4210
4211
    /* fall through to failure */
4212
0
Fail:
4213
0
    Py_XDECREF(off);
4214
0
    Py_XDECREF(dst);
4215
0
    Py_XDECREF(delta);
4216
0
    Py_XDECREF(result);
4217
0
    return NULL;
4218
0
}
4219
4220
/*
4221
 * Pickle support.  This is solely so that tzinfo subclasses can use
4222
 * pickling -- tzinfo itself is supposed to be uninstantiable.
4223
 */
4224
4225
static PyObject *
4226
tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(dummy))
4227
0
{
4228
0
    PyObject *args, *state;
4229
0
    PyObject *getinitargs;
4230
4231
0
    if (PyObject_GetOptionalAttr(self, &_Py_ID(__getinitargs__), &getinitargs) < 0) {
4232
0
        return NULL;
4233
0
    }
4234
0
    if (getinitargs != NULL) {
4235
0
        args = PyObject_CallNoArgs(getinitargs);
4236
0
        Py_DECREF(getinitargs);
4237
0
    }
4238
0
    else {
4239
0
        args = PyTuple_New(0);
4240
0
    }
4241
0
    if (args == NULL) {
4242
0
        return NULL;
4243
0
    }
4244
4245
0
    state = _PyObject_GetState(self);
4246
0
    if (state == NULL) {
4247
0
        Py_DECREF(args);
4248
0
        return NULL;
4249
0
    }
4250
4251
0
    return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
4252
0
}
4253
4254
static PyMethodDef tzinfo_methods[] = {
4255
4256
    {"tzname", tzinfo_tzname, METH_O,
4257
     PyDoc_STR("datetime -> string name of time zone.")},
4258
4259
    {"utcoffset", tzinfo_utcoffset, METH_O,
4260
     PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
4261
           "values indicating West of UTC")},
4262
4263
    {"dst", tzinfo_dst, METH_O,
4264
     PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
4265
4266
    {"fromutc", tzinfo_fromutc, METH_O,
4267
     PyDoc_STR("datetime in UTC -> datetime in local time.")},
4268
4269
    {"__reduce__",  tzinfo_reduce, METH_NOARGS,
4270
     PyDoc_STR("-> (cls, state)")},
4271
4272
    {NULL, NULL}
4273
};
4274
4275
static const char tzinfo_doc[] =
4276
PyDoc_STR("Abstract base class for time zone info objects.\n\n"
4277
          "Subclasses must override the tzname(), utcoffset() and dst() methods.");
4278
4279
static PyTypeObject PyDateTime_TZInfoType = {
4280
    PyVarObject_HEAD_INIT(NULL, 0)
4281
    "datetime.tzinfo",                          /* tp_name */
4282
    sizeof(PyDateTime_TZInfo),                  /* tp_basicsize */
4283
    0,                                          /* tp_itemsize */
4284
    0,                                          /* tp_dealloc */
4285
    0,                                          /* tp_vectorcall_offset */
4286
    0,                                          /* tp_getattr */
4287
    0,                                          /* tp_setattr */
4288
    0,                                          /* tp_as_async */
4289
    0,                                          /* tp_repr */
4290
    0,                                          /* tp_as_number */
4291
    0,                                          /* tp_as_sequence */
4292
    0,                                          /* tp_as_mapping */
4293
    0,                                          /* tp_hash */
4294
    0,                                          /* tp_call */
4295
    0,                                          /* tp_str */
4296
    PyObject_GenericGetAttr,                    /* tp_getattro */
4297
    0,                                          /* tp_setattro */
4298
    0,                                          /* tp_as_buffer */
4299
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
4300
    tzinfo_doc,                                 /* tp_doc */
4301
    0,                                          /* tp_traverse */
4302
    0,                                          /* tp_clear */
4303
    0,                                          /* tp_richcompare */
4304
    0,                                          /* tp_weaklistoffset */
4305
    0,                                          /* tp_iter */
4306
    0,                                          /* tp_iternext */
4307
    tzinfo_methods,                             /* tp_methods */
4308
    0,                                          /* tp_members */
4309
    0,                                          /* tp_getset */
4310
    0,                                          /* tp_base */
4311
    0,                                          /* tp_dict */
4312
    0,                                          /* tp_descr_get */
4313
    0,                                          /* tp_descr_set */
4314
    0,                                          /* tp_dictoffset */
4315
    0,                                          /* tp_init */
4316
    0,                                          /* tp_alloc */
4317
    PyType_GenericNew,                          /* tp_new */
4318
    0,                                          /* tp_free */
4319
};
4320
4321
/*[clinic input]
4322
@classmethod
4323
datetime.timezone.__new__ as timezone_new
4324
4325
    offset: object(subclass_of="DELTA_TYPE(NO_STATE)")
4326
    name: unicode = NULL
4327
4328
Fixed offset from UTC implementation of tzinfo.
4329
[clinic start generated code]*/
4330
4331
static PyObject *
4332
timezone_new_impl(PyTypeObject *type, PyObject *offset, PyObject *name)
4333
/*[clinic end generated code: output=41a2dda500424187 input=d51255afe60382cd]*/
4334
4
{
4335
4
    return new_timezone(offset, name);
4336
4
}
4337
4338
static void
4339
timezone_dealloc(PyObject *op)
4340
0
{
4341
0
    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
4342
0
    Py_CLEAR(self->offset);
4343
0
    Py_CLEAR(self->name);
4344
0
    Py_TYPE(self)->tp_free(self);
4345
0
}
4346
4347
static PyObject *
4348
timezone_richcompare(PyObject *self, PyObject *other, int op)
4349
0
{
4350
0
    if (op != Py_EQ && op != Py_NE)
4351
0
        Py_RETURN_NOTIMPLEMENTED;
4352
0
    if (!PyTimezone_Check(other)) {
4353
0
        Py_RETURN_NOTIMPLEMENTED;
4354
0
    }
4355
0
    PyDateTime_TimeZone *lhs = PyTimeZone_CAST(self);
4356
0
    PyDateTime_TimeZone *rhs = PyTimeZone_CAST(other);
4357
0
    return delta_richcompare(lhs->offset, rhs->offset, op);
4358
0
}
4359
4360
static Py_hash_t
4361
timezone_hash(PyObject *op)
4362
0
{
4363
0
    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
4364
0
    return delta_hash(self->offset);
4365
0
}
4366
4367
/* Check argument type passed to tzname, utcoffset, or dst methods.
4368
   Returns 0 for good argument.  Returns -1 and sets exception info
4369
   otherwise.
4370
 */
4371
static int
4372
_timezone_check_argument(PyObject *dt, const char *meth)
4373
0
{
4374
0
    if (dt == Py_None || PyDateTime_Check(dt))
4375
0
        return 0;
4376
0
    PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
4377
0
                 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
4378
0
    return -1;
4379
0
}
4380
4381
static PyObject *
4382
timezone_repr(PyObject *op)
4383
0
{
4384
    /* Note that although timezone is not subclassable, it is convenient
4385
       to use Py_TYPE(self)->tp_name here. */
4386
0
    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
4387
0
    const char *type_name = Py_TYPE(self)->tp_name;
4388
4389
0
    if (op == CONST_UTC(NO_STATE)) {
4390
0
        return PyUnicode_FromFormat("%s.utc", type_name);
4391
0
    }
4392
4393
0
    if (self->name == NULL)
4394
0
        return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
4395
4396
0
    return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
4397
0
                                self->name);
4398
0
}
4399
4400
static PyObject *
4401
timezone_str(PyObject *op)
4402
0
{
4403
0
    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
4404
0
    int hours, minutes, seconds, microseconds;
4405
0
    PyObject *offset;
4406
0
    char sign;
4407
4408
0
    if (self->name != NULL) {
4409
0
        return Py_NewRef(self->name);
4410
0
    }
4411
0
    if ((PyObject *)self == CONST_UTC(NO_STATE) ||
4412
0
           (GET_TD_DAYS(self->offset) == 0 &&
4413
0
            GET_TD_SECONDS(self->offset) == 0 &&
4414
0
            GET_TD_MICROSECONDS(self->offset) == 0))
4415
0
    {
4416
0
        return PyUnicode_FromString("UTC");
4417
0
    }
4418
    /* Offset is normalized, so it is negative if days < 0 */
4419
0
    if (GET_TD_DAYS(self->offset) < 0) {
4420
0
        sign = '-';
4421
0
        offset = delta_negative(self->offset);
4422
0
        if (offset == NULL)
4423
0
            return NULL;
4424
0
    }
4425
0
    else {
4426
0
        sign = '+';
4427
0
        offset = Py_NewRef(self->offset);
4428
0
    }
4429
    /* Offset is not negative here. */
4430
0
    microseconds = GET_TD_MICROSECONDS(offset);
4431
0
    seconds = GET_TD_SECONDS(offset);
4432
0
    Py_DECREF(offset);
4433
0
    minutes = divmod(seconds, 60, &seconds);
4434
0
    hours = divmod(minutes, 60, &minutes);
4435
0
    if (microseconds != 0) {
4436
0
        return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
4437
0
                                    sign, hours, minutes,
4438
0
                                    seconds, microseconds);
4439
0
    }
4440
0
    if (seconds != 0) {
4441
0
        return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
4442
0
                                    sign, hours, minutes, seconds);
4443
0
    }
4444
0
    return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
4445
0
}
4446
4447
static PyObject *
4448
timezone_tzname(PyObject *op, PyObject *dt)
4449
0
{
4450
0
    if (_timezone_check_argument(dt, "tzname") == -1)
4451
0
        return NULL;
4452
4453
0
    return timezone_str(op);
4454
0
}
4455
4456
static PyObject *
4457
timezone_utcoffset(PyObject *op, PyObject *dt)
4458
0
{
4459
0
    if (_timezone_check_argument(dt, "utcoffset") == -1)
4460
0
        return NULL;
4461
4462
0
    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
4463
0
    return Py_NewRef(self->offset);
4464
0
}
4465
4466
static PyObject *
4467
timezone_dst(PyObject *op, PyObject *dt)
4468
0
{
4469
0
    if (_timezone_check_argument(dt, "dst") == -1)
4470
0
        return NULL;
4471
4472
0
    Py_RETURN_NONE;
4473
0
}
4474
4475
static PyObject *
4476
timezone_fromutc(PyObject *op, PyObject *arg)
4477
0
{
4478
0
    if (!PyDateTime_Check(arg)) {
4479
0
        PyErr_SetString(PyExc_TypeError,
4480
0
                        "fromutc: argument must be a datetime");
4481
0
        return NULL;
4482
0
    }
4483
4484
0
    PyDateTime_DateTime *dt = (PyDateTime_DateTime *)arg;  // fast safe cast
4485
0
    if (!HASTZINFO(dt) || dt->tzinfo != op) {
4486
0
        PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo is not self");
4487
0
        return NULL;
4488
0
    }
4489
4490
0
    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
4491
0
    return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
4492
0
}
4493
4494
static PyObject *
4495
timezone_getinitargs(PyObject *op, PyObject *Py_UNUSED(dummy))
4496
0
{
4497
0
    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
4498
0
    if (self->name == NULL)
4499
0
        return PyTuple_Pack(1, self->offset);
4500
0
    return _PyTuple_FromPair(self->offset, self->name);
4501
0
}
4502
4503
static PyMethodDef timezone_methods[] = {
4504
    {"tzname", timezone_tzname, METH_O,
4505
     PyDoc_STR("If name is specified when timezone is created, returns the name."
4506
               "  Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
4507
4508
    {"utcoffset", timezone_utcoffset, METH_O,
4509
     PyDoc_STR("Return fixed offset.")},
4510
4511
    {"dst", timezone_dst, METH_O,
4512
     PyDoc_STR("Return None.")},
4513
4514
    {"fromutc", timezone_fromutc, METH_O,
4515
     PyDoc_STR("datetime in UTC -> datetime in local time.")},
4516
4517
    {"__getinitargs__", timezone_getinitargs, METH_NOARGS,
4518
     PyDoc_STR("pickle support")},
4519
4520
    {NULL, NULL}
4521
};
4522
4523
static PyTypeObject PyDateTime_TimeZoneType = {
4524
    PyVarObject_HEAD_INIT(NULL, 0)
4525
    "datetime.timezone",              /* tp_name */
4526
    sizeof(PyDateTime_TimeZone),      /* tp_basicsize */
4527
    0,                                /* tp_itemsize */
4528
    timezone_dealloc,                 /* tp_dealloc */
4529
    0,                                /* tp_vectorcall_offset */
4530
    0,                                /* tp_getattr */
4531
    0,                                /* tp_setattr */
4532
    0,                                /* tp_as_async */
4533
    timezone_repr,                    /* tp_repr */
4534
    0,                                /* tp_as_number */
4535
    0,                                /* tp_as_sequence */
4536
    0,                                /* tp_as_mapping */
4537
    timezone_hash,                    /* tp_hash */
4538
    0,                                /* tp_call */
4539
    timezone_str,                     /* tp_str */
4540
    0,                                /* tp_getattro */
4541
    0,                                /* tp_setattro */
4542
    0,                                /* tp_as_buffer */
4543
    Py_TPFLAGS_DEFAULT,               /* tp_flags */
4544
    timezone_new__doc__,              /* tp_doc */
4545
    0,                                /* tp_traverse */
4546
    0,                                /* tp_clear */
4547
    timezone_richcompare,             /* tp_richcompare */
4548
    0,                                /* tp_weaklistoffset */
4549
    0,                                /* tp_iter */
4550
    0,                                /* tp_iternext */
4551
    timezone_methods,                 /* tp_methods */
4552
    0,                                /* tp_members */
4553
    0,                                /* tp_getset */
4554
    &PyDateTime_TZInfoType,           /* tp_base */
4555
    0,                                /* tp_dict */
4556
    0,                                /* tp_descr_get */
4557
    0,                                /* tp_descr_set */
4558
    0,                                /* tp_dictoffset */
4559
    0,                                /* tp_init */
4560
    0,                                /* tp_alloc */
4561
    timezone_new,                     /* tp_new */
4562
};
4563
4564
// XXX Can we make this const?
4565
static PyDateTime_TimeZone utc_timezone = {
4566
    PyObject_HEAD_INIT(&PyDateTime_TimeZoneType)
4567
    .offset = (PyObject *)&zero_delta,
4568
    .name = NULL,
4569
};
4570
4571
static PyDateTime_TimeZone *
4572
look_up_timezone(PyObject *offset, PyObject *name)
4573
76
{
4574
76
    if (offset == utc_timezone.offset && name == NULL) {
4575
0
        return (PyDateTime_TimeZone *)CONST_UTC(NO_STATE);
4576
0
    }
4577
76
    return NULL;
4578
76
}
4579
4580
4581
/*
4582
 * PyDateTime_Time implementation.
4583
 */
4584
4585
/* Accessor properties.
4586
 */
4587
4588
static PyObject *
4589
time_hour(PyObject *op, void *Py_UNUSED(closure))
4590
0
{
4591
0
    PyDateTime_Time *self = PyTime_CAST(op);
4592
0
    return PyLong_FromLong(TIME_GET_HOUR(self));
4593
0
}
4594
4595
static PyObject *
4596
time_minute(PyObject *op, void *Py_UNUSED(closure))
4597
0
{
4598
0
    PyDateTime_Time *self = PyTime_CAST(op);
4599
0
    return PyLong_FromLong(TIME_GET_MINUTE(self));
4600
0
}
4601
4602
/* The name time_second conflicted with some platform header file. */
4603
static PyObject *
4604
py_time_second(PyObject *op, void *Py_UNUSED(closure))
4605
0
{
4606
0
    PyDateTime_Time *self = PyTime_CAST(op);
4607
0
    return PyLong_FromLong(TIME_GET_SECOND(self));
4608
0
}
4609
4610
static PyObject *
4611
time_microsecond(PyObject *op, void *Py_UNUSED(closure))
4612
0
{
4613
0
    PyDateTime_Time *self = PyTime_CAST(op);
4614
0
    return PyLong_FromLong(TIME_GET_MICROSECOND(self));
4615
0
}
4616
4617
static PyObject *
4618
time_tzinfo(PyObject *op, void *Py_UNUSED(closure))
4619
0
{
4620
0
    PyDateTime_Time *self = PyTime_CAST(op);
4621
0
    PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4622
0
    return Py_NewRef(result);
4623
0
}
4624
4625
static PyObject *
4626
time_fold(PyObject *op, void *Py_UNUSED(closure))
4627
0
{
4628
0
    PyDateTime_Time *self = PyTime_CAST(op);
4629
0
    return PyLong_FromLong(TIME_GET_FOLD(self));
4630
0
}
4631
4632
static PyGetSetDef time_getset[] = {
4633
    {"hour", time_hour},
4634
    {"minute", time_minute},
4635
    {"second", py_time_second},
4636
    {"microsecond", time_microsecond},
4637
    {"tzinfo", time_tzinfo},
4638
    {"fold", time_fold},
4639
    {NULL}
4640
};
4641
4642
/*
4643
 * Constructors.
4644
 */
4645
4646
static PyObject *
4647
time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4648
0
{
4649
0
    PyDateTime_Time *me;
4650
0
    char aware = (char)(tzinfo != Py_None);
4651
4652
0
    if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4653
0
        PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4654
0
        return NULL;
4655
0
    }
4656
4657
0
    me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
4658
0
    if (me != NULL) {
4659
0
        const char *pdata = PyBytes_AS_STRING(state);
4660
4661
0
        memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
4662
0
        me->hashcode = -1;
4663
0
        me->hastzinfo = aware;
4664
0
        if (aware) {
4665
0
            me->tzinfo = Py_NewRef(tzinfo);
4666
0
        }
4667
0
        if (pdata[0] & (1 << 7)) {
4668
0
            me->data[0] -= 128;
4669
0
            me->fold = 1;
4670
0
        }
4671
0
        else {
4672
0
            me->fold = 0;
4673
0
        }
4674
0
    }
4675
0
    return (PyObject *)me;
4676
0
}
4677
4678
static PyObject *
4679
time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
4680
158
{
4681
    /* Check for invocation from pickle with __getstate__ state */
4682
158
    if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4683
0
        PyObject *state = PyTuple_GET_ITEM(args, 0);
4684
0
        PyObject *tzinfo = Py_None;
4685
0
        if (PyTuple_GET_SIZE(args) == 2) {
4686
0
            tzinfo = PyTuple_GET_ITEM(args, 1);
4687
0
        }
4688
0
        if (PyBytes_Check(state)) {
4689
0
            if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
4690
0
                (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
4691
0
            {
4692
0
                return time_from_pickle(type, state, tzinfo);
4693
0
            }
4694
0
        }
4695
0
        else if (PyUnicode_Check(state)) {
4696
0
            if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE &&
4697
0
                (0x7F & PyUnicode_READ_CHAR(state, 0)) < 24)
4698
0
            {
4699
0
                state = PyUnicode_AsLatin1String(state);
4700
0
                if (state == NULL) {
4701
0
                    if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4702
                        /* More informative error message. */
4703
0
                        PyErr_SetString(PyExc_ValueError,
4704
0
                            "Failed to encode latin1 string when unpickling "
4705
0
                            "a time object. "
4706
0
                            "pickle.load(data, encoding='latin1') is assumed.");
4707
0
                    }
4708
0
                    return NULL;
4709
0
                }
4710
0
                PyObject *self = time_from_pickle(type, state, tzinfo);
4711
0
                Py_DECREF(state);
4712
0
                return self;
4713
0
            }
4714
0
        }
4715
0
    }
4716
4717
158
    return datetime_time(type, args, kw);
4718
158
}
4719
4720
/*[clinic input]
4721
@classmethod
4722
datetime.time.__new__
4723
4724
    hour: int = 0
4725
    minute: int = 0
4726
    second: int = 0
4727
    microsecond: int = 0
4728
    tzinfo: object = None
4729
    *
4730
    fold: int = 0
4731
4732
Time with time zone.
4733
4734
All arguments are optional. tzinfo may be None, or an instance of
4735
a tzinfo subclass. The remaining arguments may be ints.
4736
[clinic start generated code]*/
4737
4738
static PyObject *
4739
datetime_time_impl(PyTypeObject *type, int hour, int minute, int second,
4740
                   int microsecond, PyObject *tzinfo, int fold)
4741
/*[clinic end generated code: output=f06bb4315225e7f6 input=0148df5e8138fe7b]*/
4742
158
{
4743
158
    return new_time_ex2(hour, minute, second, microsecond, tzinfo, fold, type);
4744
158
}
4745
4746
/*[clinic input]
4747
@classmethod
4748
datetime.time.strptime
4749
4750
    string: unicode
4751
    format: unicode
4752
    /
4753
4754
Parse string according to the given time format (like time.strptime()).
4755
4756
For a list of supported format codes, see the documentation:
4757
    https://docs.python.org/3/library/datetime.html#format-codes
4758
[clinic start generated code]*/
4759
4760
static PyObject *
4761
datetime_time_strptime_impl(PyTypeObject *type, PyObject *string,
4762
                            PyObject *format)
4763
/*[clinic end generated code: output=ae05a9bc0241d3bf input=82ba425ecacc54aa]*/
4764
0
{
4765
0
    PyObject *result;
4766
4767
0
    PyObject *module = PyImport_Import(&_Py_ID(_strptime));
4768
0
    if (module == NULL) {
4769
0
        return NULL;
4770
0
    }
4771
0
    result = PyObject_CallMethodObjArgs(module,
4772
0
                                        &_Py_ID(_strptime_datetime_time),
4773
0
                                        (PyObject *)type, string, format, NULL);
4774
0
    Py_DECREF(module);
4775
0
    return result;
4776
0
}
4777
4778
/*
4779
 * Destructor.
4780
 */
4781
4782
static void
4783
time_dealloc(PyObject *op)
4784
158
{
4785
158
    PyDateTime_Time *self = PyTime_CAST(op);
4786
158
    if (HASTZINFO(self)) {
4787
0
        Py_XDECREF(self->tzinfo);
4788
0
    }
4789
158
    Py_TYPE(self)->tp_free(self);
4790
158
}
4791
4792
/*
4793
 * Indirect access to tzinfo methods.
4794
 */
4795
4796
/* These are all METH_NOARGS, so don't need to check the arglist. */
4797
static PyObject *
4798
0
time_utcoffset(PyObject *op, PyObject *Py_UNUSED(dummy)) {
4799
0
    PyDateTime_Time *self = PyTime_CAST(op);
4800
0
    return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
4801
0
}
4802
4803
static PyObject *
4804
0
time_dst(PyObject *op, PyObject *Py_UNUSED(dummy)) {
4805
0
    PyDateTime_Time *self = PyTime_CAST(op);
4806
0
    return call_dst(GET_TIME_TZINFO(self), Py_None);
4807
0
}
4808
4809
static PyObject *
4810
0
time_tzname(PyObject *op, PyObject *Py_UNUSED(dummy)) {
4811
0
    PyDateTime_Time *self = PyTime_CAST(op);
4812
0
    return call_tzname(GET_TIME_TZINFO(self), Py_None);
4813
0
}
4814
4815
/*
4816
 * Various ways to turn a time into a string.
4817
 */
4818
4819
static PyObject *
4820
time_repr(PyObject *op)
4821
0
{
4822
0
    PyDateTime_Time *self = PyTime_CAST(op);
4823
0
    const char *type_name = Py_TYPE(self)->tp_name;
4824
0
    int h = TIME_GET_HOUR(self);
4825
0
    int m = TIME_GET_MINUTE(self);
4826
0
    int s = TIME_GET_SECOND(self);
4827
0
    int us = TIME_GET_MICROSECOND(self);
4828
0
    int fold = TIME_GET_FOLD(self);
4829
0
    PyObject *result = NULL;
4830
4831
0
    if (us)
4832
0
        result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
4833
0
                                      type_name, h, m, s, us);
4834
0
    else if (s)
4835
0
        result = PyUnicode_FromFormat("%s(%d, %d, %d)",
4836
0
                                      type_name, h, m, s);
4837
0
    else
4838
0
        result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
4839
0
    if (result != NULL && HASTZINFO(self))
4840
0
        result = append_keyword_tzinfo(result, self->tzinfo);
4841
0
    if (result != NULL && fold)
4842
0
        result = append_keyword_fold(result, fold);
4843
0
    return result;
4844
0
}
4845
4846
static PyObject *
4847
time_str(PyObject *op)
4848
0
{
4849
0
    return PyObject_CallMethodNoArgs(op, &_Py_ID(isoformat));
4850
0
}
4851
4852
/*[clinic input]
4853
datetime.time.isoformat
4854
4855
    timespec: str(c_default="NULL") = 'auto'
4856
4857
Return the time formatted according to ISO.
4858
4859
The full format is 'HH:MM:SS.mmmmmm+zz:zz'. By default, the fractional
4860
part is omitted if self.microsecond == 0.
4861
4862
The optional argument timespec specifies the number of additional
4863
terms of the time to include. Valid options are 'auto', 'hours',
4864
'minutes', 'seconds', 'milliseconds' and 'microseconds'.
4865
[clinic start generated code]*/
4866
4867
static PyObject *
4868
datetime_time_isoformat_impl(PyDateTime_Time *self, const char *timespec)
4869
/*[clinic end generated code: output=2bcc7cab65c35545 input=afbbbd953d10ad07]*/
4870
0
{
4871
0
    char buf[100];
4872
4873
0
    PyObject *result;
4874
0
    int us = TIME_GET_MICROSECOND(self);
4875
0
    static const char * const specs[][2] = {
4876
0
        {"hours", "%02d"},
4877
0
        {"minutes", "%02d:%02d"},
4878
0
        {"seconds", "%02d:%02d:%02d"},
4879
0
        {"milliseconds", "%02d:%02d:%02d.%03d"},
4880
0
        {"microseconds", "%02d:%02d:%02d.%06d"},
4881
0
    };
4882
0
    size_t given_spec;
4883
4884
0
    if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4885
0
        if (us == 0) {
4886
            /* seconds */
4887
0
            given_spec = 2;
4888
0
        }
4889
0
        else {
4890
            /* microseconds */
4891
0
            given_spec = 4;
4892
0
        }
4893
0
    }
4894
0
    else {
4895
0
        for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4896
0
            if (strcmp(timespec, specs[given_spec][0]) == 0) {
4897
0
                if (given_spec == 3) {
4898
                    /* milliseconds */
4899
0
                    us = us / 1000;
4900
0
                }
4901
0
                break;
4902
0
            }
4903
0
        }
4904
0
    }
4905
4906
0
    if (given_spec == Py_ARRAY_LENGTH(specs)) {
4907
0
        PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4908
0
        return NULL;
4909
0
    }
4910
0
    else {
4911
0
        result = PyUnicode_FromFormat(specs[given_spec][1],
4912
0
                                      TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4913
0
                                      TIME_GET_SECOND(self), us);
4914
0
    }
4915
4916
0
    if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
4917
0
        return result;
4918
4919
    /* We need to append the UTC offset. */
4920
0
    if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4921
0
                         Py_None) < 0) {
4922
0
        Py_DECREF(result);
4923
0
        return NULL;
4924
0
    }
4925
0
    PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4926
0
    return result;
4927
0
}
4928
4929
/*[clinic input]
4930
@permit_long_docstring_body
4931
datetime.time.strftime
4932
4933
    format: unicode
4934
4935
Format using strftime().
4936
4937
The date part of the timestamp passed to underlying strftime should not be used.
4938
4939
For a list of supported format codes, see the documentation:
4940
    https://docs.python.org/3/library/datetime.html#format-codes
4941
[clinic start generated code]*/
4942
4943
static PyObject *
4944
datetime_time_strftime_impl(PyDateTime_Time *self, PyObject *format)
4945
/*[clinic end generated code: output=10f65af20e2a78c7 input=c4a5bbecd798654b]*/
4946
0
{
4947
0
    PyObject *result;
4948
0
    PyObject *tuple;
4949
4950
    /* Python's strftime does insane things with the year part of the
4951
     * timetuple.  The year is forced to (the otherwise nonsensical)
4952
     * 1900 to work around that.
4953
     */
4954
0
    tuple = Py_BuildValue("iiiiiiiii",
4955
0
                          1900, 1, 1, /* year, month, day */
4956
0
                  TIME_GET_HOUR(self),
4957
0
                  TIME_GET_MINUTE(self),
4958
0
                  TIME_GET_SECOND(self),
4959
0
                  0, 1, -1); /* weekday, daynum, dst */
4960
0
    if (tuple == NULL)
4961
0
        return NULL;
4962
0
    assert(PyTuple_Size(tuple) == 9);
4963
0
    result = wrap_strftime((PyObject *)self, format, tuple,
4964
0
                           Py_None);
4965
0
    Py_DECREF(tuple);
4966
0
    return result;
4967
0
}
4968
4969
/*[clinic input]
4970
datetime.time.__format__
4971
4972
    self: self(type="PyObject *")
4973
    format: unicode
4974
    /
4975
4976
Formats self with strftime.
4977
[clinic start generated code]*/
4978
4979
static PyObject *
4980
datetime_time___format___impl(PyObject *self, PyObject *format)
4981
/*[clinic end generated code: output=4646451f7a5d2156 input=6a858ae787d20230]*/
4982
0
{
4983
    /* if the format is zero length, return str(self) */
4984
0
    if (PyUnicode_GetLength(format) == 0)
4985
0
        return PyObject_Str(self);
4986
4987
0
    return PyObject_CallMethodOneArg(self, &_Py_ID(strftime), format);
4988
0
}
4989
4990
/*
4991
 * Miscellaneous methods.
4992
 */
4993
4994
static PyObject *
4995
time_richcompare(PyObject *self, PyObject *other, int op)
4996
0
{
4997
0
    PyObject *result = NULL;
4998
0
    PyObject *offset1, *offset2;
4999
0
    int diff;
5000
5001
0
    if (! PyTime_Check(other))
5002
0
        Py_RETURN_NOTIMPLEMENTED;
5003
5004
0
    if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
5005
0
        diff = memcmp(((PyDateTime_Time *)self)->data,
5006
0
                      ((PyDateTime_Time *)other)->data,
5007
0
                      _PyDateTime_TIME_DATASIZE);
5008
0
        return diff_to_bool(diff, op);
5009
0
    }
5010
0
    offset1 = time_utcoffset(self, NULL);
5011
0
    if (offset1 == NULL)
5012
0
        return NULL;
5013
0
    offset2 = time_utcoffset(other, NULL);
5014
0
    if (offset2 == NULL)
5015
0
        goto done;
5016
    /* If they're both naive, or both aware and have the same offsets,
5017
     * we get off cheap.  Note that if they're both naive, offset1 ==
5018
     * offset2 == Py_None at this point.
5019
     */
5020
0
    if ((offset1 == offset2) ||
5021
0
        (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5022
0
         delta_cmp(offset1, offset2) == 0)) {
5023
0
        diff = memcmp(((PyDateTime_Time *)self)->data,
5024
0
                      ((PyDateTime_Time *)other)->data,
5025
0
                      _PyDateTime_TIME_DATASIZE);
5026
0
        result = diff_to_bool(diff, op);
5027
0
    }
5028
    /* The hard case: both aware with different UTC offsets */
5029
0
    else if (offset1 != Py_None && offset2 != Py_None) {
5030
0
        int offsecs1, offsecs2;
5031
0
        assert(offset1 != offset2); /* else last "if" handled it */
5032
0
        offsecs1 = TIME_GET_HOUR(self) * 3600 +
5033
0
                   TIME_GET_MINUTE(self) * 60 +
5034
0
                   TIME_GET_SECOND(self) -
5035
0
                   GET_TD_DAYS(offset1) * 86400 -
5036
0
                   GET_TD_SECONDS(offset1);
5037
0
        offsecs2 = TIME_GET_HOUR(other) * 3600 +
5038
0
                   TIME_GET_MINUTE(other) * 60 +
5039
0
                   TIME_GET_SECOND(other) -
5040
0
                   GET_TD_DAYS(offset2) * 86400 -
5041
0
                   GET_TD_SECONDS(offset2);
5042
0
        diff = offsecs1 - offsecs2;
5043
0
        if (diff == 0)
5044
0
            diff = TIME_GET_MICROSECOND(self) -
5045
0
                   TIME_GET_MICROSECOND(other);
5046
0
        result = diff_to_bool(diff, op);
5047
0
    }
5048
0
    else if (op == Py_EQ) {
5049
0
        result = Py_NewRef(Py_False);
5050
0
    }
5051
0
    else if (op == Py_NE) {
5052
0
        result = Py_NewRef(Py_True);
5053
0
    }
5054
0
    else {
5055
0
        PyErr_SetString(PyExc_TypeError,
5056
0
                        "can't compare offset-naive and "
5057
0
                        "offset-aware times");
5058
0
    }
5059
0
 done:
5060
0
    Py_DECREF(offset1);
5061
0
    Py_XDECREF(offset2);
5062
0
    return result;
5063
0
}
5064
5065
static Py_hash_t
5066
time_hash(PyObject *op)
5067
0
{
5068
0
    PyDateTime_Time *self = PyTime_CAST(op);
5069
0
    Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
5070
0
    if (hash == -1) {
5071
0
        PyObject *offset, *self0;
5072
0
        if (TIME_GET_FOLD(self)) {
5073
0
            self0 = new_time_ex2(TIME_GET_HOUR(self),
5074
0
                                 TIME_GET_MINUTE(self),
5075
0
                                 TIME_GET_SECOND(self),
5076
0
                                 TIME_GET_MICROSECOND(self),
5077
0
                                 HASTZINFO(self) ? self->tzinfo : Py_None,
5078
0
                                 0, Py_TYPE(self));
5079
0
            if (self0 == NULL)
5080
0
                return -1;
5081
0
        }
5082
0
        else {
5083
0
            self0 = Py_NewRef(self);
5084
0
        }
5085
0
        offset = time_utcoffset(self0, NULL);
5086
0
        Py_DECREF(self0);
5087
5088
0
        if (offset == NULL)
5089
0
            return -1;
5090
5091
        /* Reduce this to a hash of another object. */
5092
0
        if (offset == Py_None) {
5093
0
            hash = generic_hash(
5094
0
                (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
5095
0
            FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
5096
0
        } else {
5097
0
            PyObject *temp1, *temp2;
5098
0
            int seconds, microseconds;
5099
0
            assert(HASTZINFO(self));
5100
0
            seconds = TIME_GET_HOUR(self) * 3600 +
5101
0
                      TIME_GET_MINUTE(self) * 60 +
5102
0
                      TIME_GET_SECOND(self);
5103
0
            microseconds = TIME_GET_MICROSECOND(self);
5104
0
            temp1 = new_delta(0, seconds, microseconds, 1);
5105
0
            if (temp1 == NULL) {
5106
0
                Py_DECREF(offset);
5107
0
                return -1;
5108
0
            }
5109
0
            temp2 = delta_subtract(temp1, offset);
5110
0
            Py_DECREF(temp1);
5111
0
            if (temp2 == NULL) {
5112
0
                Py_DECREF(offset);
5113
0
                return -1;
5114
0
            }
5115
0
            hash = PyObject_Hash(temp2);
5116
0
            FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
5117
0
            Py_DECREF(temp2);
5118
0
        }
5119
0
        Py_DECREF(offset);
5120
0
    }
5121
0
    return hash;
5122
0
}
5123
5124
/*[clinic input]
5125
datetime.time.replace
5126
5127
    hour: int(c_default="TIME_GET_HOUR(self)") = unchanged
5128
    minute: int(c_default="TIME_GET_MINUTE(self)") = unchanged
5129
    second: int(c_default="TIME_GET_SECOND(self)") = unchanged
5130
    microsecond: int(c_default="TIME_GET_MICROSECOND(self)") = unchanged
5131
    tzinfo: object(c_default="HASTZINFO(self) ? ((PyDateTime_Time *)self)->tzinfo : Py_None") = unchanged
5132
    *
5133
    fold: int(c_default="TIME_GET_FOLD(self)") = unchanged
5134
5135
Return time with new specified fields.
5136
[clinic start generated code]*/
5137
5138
static PyObject *
5139
datetime_time_replace_impl(PyDateTime_Time *self, int hour, int minute,
5140
                           int second, int microsecond, PyObject *tzinfo,
5141
                           int fold)
5142
/*[clinic end generated code: output=0b89a44c299e4f80 input=abf23656e8df4e97]*/
5143
0
{
5144
0
    return new_time_subclass_fold_ex(hour, minute, second, microsecond, tzinfo,
5145
0
                                     fold, Py_TYPE(self));
5146
0
}
5147
5148
/*[clinic input]
5149
@classmethod
5150
datetime.time.fromisoformat
5151
5152
    string: unicode
5153
    /
5154
5155
Construct a time from a string in ISO 8601 format.
5156
[clinic start generated code]*/
5157
5158
static PyObject *
5159
datetime_time_fromisoformat_impl(PyTypeObject *type, PyObject *string)
5160
/*[clinic end generated code: output=97c57e896e7f2535 input=bdb4b8abea9cd688]*/
5161
0
{
5162
0
    Py_ssize_t len;
5163
0
    const char *p = PyUnicode_AsUTF8AndSize(string, &len);
5164
5165
0
    if (p == NULL) {
5166
0
        goto invalid_string_error;
5167
0
    }
5168
5169
    // The spec actually requires that time-only ISO 8601 strings start with
5170
    // T, but the extended format allows this to be omitted as long as there
5171
    // is no ambiguity with date strings.
5172
0
    if (*p == 'T') {
5173
0
        ++p;
5174
0
        len -= 1;
5175
0
    }
5176
5177
0
    int hour = 0, minute = 0, second = 0, microsecond = 0;
5178
0
    int tzoffset = 0, tzimicrosecond = 0;
5179
0
    int rv = parse_isoformat_time(p, len,
5180
0
                                  &hour, &minute, &second, &microsecond,
5181
0
                                  &tzoffset, &tzimicrosecond);
5182
5183
0
    if (rv < 0) {
5184
0
        if (rv == -6) {
5185
0
            goto error;
5186
0
        }
5187
0
        goto invalid_string_error;
5188
0
    }
5189
5190
0
    if (hour == 24) {
5191
0
        if (minute == 0 && second == 0 && microsecond == 0) {
5192
0
            hour = 0;
5193
0
        } else {
5194
0
            goto invalid_iso_midnight;
5195
0
        }
5196
0
    }
5197
5198
0
    PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
5199
0
                                                     tzimicrosecond);
5200
5201
0
    if (tzinfo == NULL) {
5202
0
        return NULL;
5203
0
    }
5204
5205
0
    PyObject *t;
5206
0
    if (type == TIME_TYPE(NO_STATE)) {
5207
0
        t = new_time(hour, minute, second, microsecond, tzinfo, 0);
5208
0
    } else {
5209
0
        t = PyObject_CallFunction((PyObject *)type, "iiiiO",
5210
0
                                  hour, minute, second, microsecond, tzinfo);
5211
0
    }
5212
5213
0
    Py_DECREF(tzinfo);
5214
0
    return t;
5215
5216
0
invalid_iso_midnight:
5217
0
    PyErr_SetString(PyExc_ValueError, "minute, second, and microsecond must be 0 when hour is 24");
5218
0
    return NULL;
5219
5220
0
invalid_string_error:
5221
0
    PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", string);
5222
0
    return NULL;
5223
5224
0
error:
5225
0
    return NULL;
5226
0
}
5227
5228
5229
/* Pickle support, a simple use of __reduce__. */
5230
5231
/* Let basestate be the non-tzinfo data string.
5232
 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5233
 * So it's a tuple in any (non-error) case.
5234
 * __getstate__ isn't exposed.
5235
 */
5236
static PyObject *
5237
time_getstate(PyDateTime_Time *self, int proto)
5238
0
{
5239
0
    PyObject *basestate;
5240
0
    PyObject *result = NULL;
5241
5242
0
    basestate =  PyBytes_FromStringAndSize((char *)self->data,
5243
0
                                            _PyDateTime_TIME_DATASIZE);
5244
0
    if (basestate != NULL) {
5245
0
        if (proto > 3 && TIME_GET_FOLD(self))
5246
            /* Set the first bit of the first byte */
5247
0
            PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
5248
0
        if (! HASTZINFO(self) || self->tzinfo == Py_None)
5249
0
            result = PyTuple_Pack(1, basestate);
5250
0
        else
5251
0
            result = _PyTuple_FromPair(basestate, self->tzinfo);
5252
0
        Py_DECREF(basestate);
5253
0
    }
5254
0
    return result;
5255
0
}
5256
5257
/*[clinic input]
5258
datetime.time.__reduce_ex__
5259
5260
    proto: int
5261
    /
5262
[clinic start generated code]*/
5263
5264
static PyObject *
5265
datetime_time___reduce_ex___impl(PyDateTime_Time *self, int proto)
5266
/*[clinic end generated code: output=ccfab65f5c320c1b input=4cd06bb3ac3657bb]*/
5267
0
{
5268
0
    return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
5269
0
}
5270
5271
/*[clinic input]
5272
datetime.time.__reduce__
5273
[clinic start generated code]*/
5274
5275
static PyObject *
5276
datetime_time___reduce___impl(PyDateTime_Time *self)
5277
/*[clinic end generated code: output=9a2fcc87e64ce300 input=0fb8dd14d275857f]*/
5278
0
{
5279
0
    return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
5280
0
}
5281
5282
static PyMethodDef time_methods[] = {
5283
5284
    /* Class method: */
5285
5286
    DATETIME_TIME_FROMISOFORMAT_METHODDEF
5287
    DATETIME_TIME_STRPTIME_METHODDEF
5288
5289
    /* Instance methods: */
5290
5291
    DATETIME_TIME_ISOFORMAT_METHODDEF
5292
    DATETIME_TIME_STRFTIME_METHODDEF
5293
    DATETIME_TIME___FORMAT___METHODDEF
5294
5295
    {"utcoffset", time_utcoffset, METH_NOARGS,
5296
     PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
5297
5298
    {"tzname", time_tzname, METH_NOARGS,
5299
     PyDoc_STR("Return self.tzinfo.tzname(self).")},
5300
5301
    {"dst", time_dst, METH_NOARGS,
5302
     PyDoc_STR("Return self.tzinfo.dst(self).")},
5303
5304
    DATETIME_TIME_REPLACE_METHODDEF
5305
5306
    {"__replace__", _PyCFunction_CAST(datetime_time_replace), METH_FASTCALL | METH_KEYWORDS,
5307
     PyDoc_STR("__replace__($self, /, **changes)\n--\n\nThe same as replace().")},
5308
5309
    DATETIME_TIME___REDUCE_EX___METHODDEF
5310
    DATETIME_TIME___REDUCE___METHODDEF
5311
5312
    {NULL,      NULL}
5313
};
5314
5315
static PyTypeObject PyDateTime_TimeType = {
5316
    PyVarObject_HEAD_INIT(NULL, 0)
5317
    "datetime.time",                            /* tp_name */
5318
    sizeof(PyDateTime_Time),                    /* tp_basicsize */
5319
    0,                                          /* tp_itemsize */
5320
    time_dealloc,                               /* tp_dealloc */
5321
    0,                                          /* tp_vectorcall_offset */
5322
    0,                                          /* tp_getattr */
5323
    0,                                          /* tp_setattr */
5324
    0,                                          /* tp_as_async */
5325
    time_repr,                                  /* tp_repr */
5326
    0,                                          /* tp_as_number */
5327
    0,                                          /* tp_as_sequence */
5328
    0,                                          /* tp_as_mapping */
5329
    time_hash,                                  /* tp_hash */
5330
    0,                                          /* tp_call */
5331
    time_str,                                   /* tp_str */
5332
    PyObject_GenericGetAttr,                    /* tp_getattro */
5333
    0,                                          /* tp_setattro */
5334
    0,                                          /* tp_as_buffer */
5335
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
5336
    datetime_time__doc__,                       /* tp_doc */
5337
    0,                                          /* tp_traverse */
5338
    0,                                          /* tp_clear */
5339
    time_richcompare,                           /* tp_richcompare */
5340
    0,                                          /* tp_weaklistoffset */
5341
    0,                                          /* tp_iter */
5342
    0,                                          /* tp_iternext */
5343
    time_methods,                               /* tp_methods */
5344
    0,                                          /* tp_members */
5345
    time_getset,                                /* tp_getset */
5346
    0,                                          /* tp_base */
5347
    0,                                          /* tp_dict */
5348
    0,                                          /* tp_descr_get */
5349
    0,                                          /* tp_descr_set */
5350
    0,                                          /* tp_dictoffset */
5351
    0,                                          /* tp_init */
5352
    time_alloc,                                 /* tp_alloc */
5353
    time_new,                                   /* tp_new */
5354
    0,                                          /* tp_free */
5355
};
5356
5357
/*
5358
 * PyDateTime_DateTime implementation.
5359
 */
5360
5361
/* Accessor properties.  Properties for day, month, and year are inherited
5362
 * from date.
5363
 */
5364
5365
static PyObject *
5366
datetime_hour(PyObject *op, void *Py_UNUSED(closure))
5367
8
{
5368
8
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
5369
8
    return PyLong_FromLong(DATE_GET_HOUR(self));
5370
8
}
5371
5372
static PyObject *
5373
datetime_minute(PyObject *op, void *Py_UNUSED(closure))
5374
8
{
5375
8
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
5376
8
    return PyLong_FromLong(DATE_GET_MINUTE(self));
5377
8
}
5378
5379
static PyObject *
5380
datetime_second(PyObject *op, void *Py_UNUSED(closure))
5381
8
{
5382
8
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
5383
8
    return PyLong_FromLong(DATE_GET_SECOND(self));
5384
8
}
5385
5386
static PyObject *
5387
datetime_microsecond(PyObject *op, void *Py_UNUSED(closure))
5388
0
{
5389
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
5390
0
    return PyLong_FromLong(DATE_GET_MICROSECOND(self));
5391
0
}
5392
5393
static PyObject *
5394
datetime_tzinfo(PyObject *op, void *Py_UNUSED(closure))
5395
0
{
5396
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
5397
0
    PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
5398
0
    return Py_NewRef(result);
5399
0
}
5400
5401
static PyObject *
5402
datetime_fold(PyObject *op, void *Py_UNUSED(closure))
5403
0
{
5404
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
5405
0
    return PyLong_FromLong(DATE_GET_FOLD(self));
5406
0
}
5407
5408
static PyGetSetDef datetime_getset[] = {
5409
    {"hour", datetime_hour},
5410
    {"minute", datetime_minute},
5411
    {"second", datetime_second},
5412
    {"microsecond", datetime_microsecond},
5413
    {"tzinfo", datetime_tzinfo},
5414
    {"fold", datetime_fold},
5415
    {NULL}
5416
};
5417
5418
/*
5419
 * Constructors.
5420
 */
5421
5422
static PyObject *
5423
datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
5424
0
{
5425
0
    PyDateTime_DateTime *me;
5426
0
    char aware = (char)(tzinfo != Py_None);
5427
5428
0
    if (aware && check_tzinfo_subclass(tzinfo) < 0) {
5429
0
        PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
5430
0
        return NULL;
5431
0
    }
5432
5433
0
    me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
5434
0
    if (me != NULL) {
5435
0
        const char *pdata = PyBytes_AS_STRING(state);
5436
5437
0
        memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
5438
0
        me->hashcode = -1;
5439
0
        me->hastzinfo = aware;
5440
0
        if (aware) {
5441
0
            me->tzinfo = Py_NewRef(tzinfo);
5442
0
        }
5443
0
        if (pdata[2] & (1 << 7)) {
5444
0
            me->data[2] -= 128;
5445
0
            me->fold = 1;
5446
0
        }
5447
0
        else {
5448
0
            me->fold = 0;
5449
0
        }
5450
0
    }
5451
0
    return (PyObject *)me;
5452
0
}
5453
5454
static PyObject *
5455
datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
5456
105
{
5457
    /* Check for invocation from pickle with __getstate__ state */
5458
105
    if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
5459
0
        PyObject *state = PyTuple_GET_ITEM(args, 0);
5460
0
        PyObject *tzinfo = Py_None;
5461
0
        if (PyTuple_GET_SIZE(args) == 2) {
5462
0
            tzinfo = PyTuple_GET_ITEM(args, 1);
5463
0
        }
5464
0
        if (PyBytes_Check(state)) {
5465
0
            if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
5466
0
                MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
5467
0
            {
5468
0
                return datetime_from_pickle(type, state, tzinfo);
5469
0
            }
5470
0
        }
5471
0
        else if (PyUnicode_Check(state)) {
5472
0
            if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE &&
5473
0
                MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F))
5474
0
            {
5475
0
                state = PyUnicode_AsLatin1String(state);
5476
0
                if (state == NULL) {
5477
0
                    if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
5478
                        /* More informative error message. */
5479
0
                        PyErr_SetString(PyExc_ValueError,
5480
0
                            "Failed to encode latin1 string when unpickling "
5481
0
                            "a datetime object. "
5482
0
                            "pickle.load(data, encoding='latin1') is assumed.");
5483
0
                    }
5484
0
                    return NULL;
5485
0
                }
5486
0
                PyObject *self = datetime_from_pickle(type, state, tzinfo);
5487
0
                Py_DECREF(state);
5488
0
                return self;
5489
0
            }
5490
0
        }
5491
0
    }
5492
5493
105
    return datetime_datetime(type, args, kw);
5494
105
}
5495
5496
/*[clinic input]
5497
@classmethod
5498
datetime.datetime.__new__
5499
5500
    year: int
5501
    month: int
5502
    day: int
5503
    hour: int = 0
5504
    minute: int = 0
5505
    second: int = 0
5506
    microsecond: int = 0
5507
    tzinfo: object = None
5508
    *
5509
    fold: int = 0
5510
5511
A combination of a date and a time.
5512
5513
The year, month and day arguments are required. tzinfo may be None, or an
5514
instance of a tzinfo subclass. The remaining arguments may be ints.
5515
[clinic start generated code]*/
5516
5517
static PyObject *
5518
datetime_datetime_impl(PyTypeObject *type, int year, int month, int day,
5519
                       int hour, int minute, int second, int microsecond,
5520
                       PyObject *tzinfo, int fold)
5521
/*[clinic end generated code: output=47983ddb47d36037 input=2af468d7a9c1e568]*/
5522
105
{
5523
105
    return new_datetime_ex2(year, month, day,
5524
105
                            hour, minute, second, microsecond,
5525
105
                            tzinfo, fold, type);
5526
105
}
5527
5528
/* TM_FUNC is the shared type of _PyTime_localtime() and
5529
 * _PyTime_gmtime(). */
5530
typedef int (*TM_FUNC)(time_t timer, struct tm*);
5531
5532
/* As of version 2015f max fold in IANA database is
5533
 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
5534
static long long max_fold_seconds = 24 * 3600;
5535
/* NB: date(1970,1,1).toordinal() == 719163 */
5536
static long long epoch = 719163LL * 24 * 60 * 60;
5537
5538
static long long
5539
utc_to_seconds(int year, int month, int day,
5540
               int hour, int minute, int second)
5541
0
{
5542
0
    long long ordinal;
5543
5544
    /* ymd_to_ord() doesn't support year <= 0 */
5545
0
    if (year < MINYEAR || year > MAXYEAR) {
5546
0
        PyErr_Format(PyExc_ValueError,
5547
0
                     "year must be in %d..%d, not %d", MINYEAR, MAXYEAR, year);
5548
0
        return -1;
5549
0
    }
5550
5551
0
    ordinal = ymd_to_ord(year, month, day);
5552
0
    return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
5553
0
}
5554
5555
static long long
5556
local(long long u)
5557
0
{
5558
0
    struct tm local_time;
5559
0
    time_t t;
5560
0
    u -= epoch;
5561
0
    t = u;
5562
0
    if (t != u) {
5563
0
        PyErr_SetString(PyExc_OverflowError,
5564
0
        "timestamp out of range for platform time_t");
5565
0
        return -1;
5566
0
    }
5567
0
    if (_PyTime_localtime(t, &local_time) != 0)
5568
0
        return -1;
5569
0
    return utc_to_seconds(local_time.tm_year + 1900,
5570
0
                          local_time.tm_mon + 1,
5571
0
                          local_time.tm_mday,
5572
0
                          local_time.tm_hour,
5573
0
                          local_time.tm_min,
5574
0
                          local_time.tm_sec);
5575
0
}
5576
5577
/* Internal helper.
5578
 * Build datetime from a time_t and a distinct count of microseconds.
5579
 * Pass localtime or gmtime for f, to control the interpretation of timet.
5580
 */
5581
static PyObject *
5582
datetime_from_timet_and_us(PyTypeObject *cls, TM_FUNC f, time_t timet, int us,
5583
                           PyObject *tzinfo)
5584
0
{
5585
0
    struct tm tm;
5586
0
    int year, month, day, hour, minute, second, fold = 0;
5587
5588
0
    if (f(timet, &tm) != 0)
5589
0
        return NULL;
5590
5591
0
    year = tm.tm_year + 1900;
5592
0
    month = tm.tm_mon + 1;
5593
0
    day = tm.tm_mday;
5594
0
    hour = tm.tm_hour;
5595
0
    minute = tm.tm_min;
5596
    /* The platform localtime/gmtime may insert leap seconds,
5597
     * indicated by tm.tm_sec > 59.  We don't care about them,
5598
     * except to the extent that passing them on to the datetime
5599
     * constructor would raise ValueError for a reason that
5600
     * made no sense to the user.
5601
     */
5602
0
    second = Py_MIN(59, tm.tm_sec);
5603
5604
    /* local timezone requires to compute fold */
5605
0
    if (tzinfo == Py_None && f == _PyTime_localtime) {
5606
0
        long long probe_seconds, result_seconds, transition;
5607
5608
0
        result_seconds = utc_to_seconds(year, month, day,
5609
0
                                        hour, minute, second);
5610
0
        if (result_seconds == -1 && PyErr_Occurred()) {
5611
0
            return NULL;
5612
0
        }
5613
5614
        /* Probe max_fold_seconds to detect a fold. */
5615
0
        probe_seconds = local(epoch + timet - max_fold_seconds);
5616
0
        if (probe_seconds == -1)
5617
0
            return NULL;
5618
0
        transition = result_seconds - probe_seconds - max_fold_seconds;
5619
0
        if (transition < 0) {
5620
0
            probe_seconds = local(epoch + timet + transition);
5621
0
            if (probe_seconds == -1)
5622
0
                return NULL;
5623
0
            if (probe_seconds == result_seconds)
5624
0
                fold = 1;
5625
0
        }
5626
0
    }
5627
0
    return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
5628
0
                                         second, us, tzinfo, fold, cls);
5629
0
}
5630
5631
/* Internal helper.
5632
 * Build datetime from a Python timestamp.  Pass localtime or gmtime for f,
5633
 * to control the interpretation of the timestamp.  Since a double doesn't
5634
 * have enough bits to cover a datetime's full range of precision, it's
5635
 * better to call datetime_from_timet_and_us provided you have a way
5636
 * to get that much precision (e.g., C time() isn't good enough).
5637
 */
5638
static PyObject *
5639
datetime_from_timestamp(PyTypeObject *cls, TM_FUNC f, PyObject *timestamp,
5640
                        PyObject *tzinfo)
5641
0
{
5642
0
    time_t timet;
5643
0
    long us;
5644
5645
0
    if (_PyTime_ObjectToTimeval(timestamp,
5646
0
                                &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
5647
0
        return NULL;
5648
5649
0
    return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
5650
0
}
5651
5652
/* Internal helper.
5653
 * Build most accurate possible datetime for current time.  Pass localtime or
5654
 * gmtime for f as appropriate.
5655
 */
5656
static PyObject *
5657
datetime_best_possible(PyTypeObject *cls, TM_FUNC f, PyObject *tzinfo)
5658
0
{
5659
0
    PyTime_t ts;
5660
0
    if (PyTime_Time(&ts) < 0) {
5661
0
        return NULL;
5662
0
    }
5663
5664
0
    time_t secs;
5665
0
    int us;
5666
5667
0
    if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_HALF_EVEN) < 0) {
5668
0
        return NULL;
5669
0
    }
5670
0
    assert(0 <= us && us <= 999999);
5671
5672
0
    return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
5673
0
}
5674
5675
/*[clinic input]
5676
5677
@classmethod
5678
datetime.datetime.now
5679
5680
    tz: object = None
5681
        Timezone object.
5682
5683
Returns new datetime object representing current time local to tz.
5684
5685
If no tz is specified, uses local timezone.
5686
[clinic start generated code]*/
5687
5688
static PyObject *
5689
datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
5690
/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
5691
0
{
5692
0
    PyObject *self;
5693
5694
    /* Return best possible local time -- this isn't constrained by the
5695
     * precision of a timestamp.
5696
     */
5697
0
    if (check_tzinfo_subclass(tz) < 0)
5698
0
        return NULL;
5699
5700
0
    self = datetime_best_possible(type,
5701
0
                                  tz == Py_None ? _PyTime_localtime :
5702
0
                                  _PyTime_gmtime,
5703
0
                                  tz);
5704
0
    if (self != NULL && tz != Py_None) {
5705
        /* Convert UTC to tzinfo's zone. */
5706
0
        PyObject *res = PyObject_CallMethodOneArg(tz, &_Py_ID(fromutc), self);
5707
0
        Py_DECREF(self);
5708
0
        return res;
5709
0
    }
5710
0
    return self;
5711
0
}
5712
5713
/* Return best possible UTC time -- this isn't constrained by the
5714
 * precision of a timestamp.
5715
 */
5716
/*[clinic input]
5717
@classmethod
5718
datetime.datetime.utcnow
5719
5720
Return a new datetime representing UTC day and time.
5721
[clinic start generated code]*/
5722
5723
static PyObject *
5724
datetime_datetime_utcnow_impl(PyTypeObject *type)
5725
/*[clinic end generated code: output=cfcfe71c6c916ba9 input=576eff2b222b80a1]*/
5726
0
{
5727
0
    if (PyErr_WarnEx(PyExc_DeprecationWarning,
5728
0
        "datetime.datetime.utcnow() is deprecated and scheduled for removal in a "
5729
0
        "future version. Use timezone-aware objects to represent datetimes "
5730
0
        "in UTC: datetime.datetime.now(datetime.UTC).", 1))
5731
0
    {
5732
0
        return NULL;
5733
0
    }
5734
0
    return datetime_best_possible(type, _PyTime_gmtime, Py_None);
5735
0
}
5736
5737
/*[clinic input]
5738
@permit_long_docstring_body
5739
@classmethod
5740
datetime.datetime.fromtimestamp
5741
5742
    timestamp: object
5743
    tz as tzinfo: object = None
5744
5745
Create a datetime from a POSIX timestamp.
5746
5747
The timestamp is a number, e.g. created via time.time(), that is interpreted
5748
as local time.
5749
[clinic start generated code]*/
5750
5751
static PyObject *
5752
datetime_datetime_fromtimestamp_impl(PyTypeObject *type, PyObject *timestamp,
5753
                                     PyObject *tzinfo)
5754
/*[clinic end generated code: output=9c47ea2b2ebdaded input=d6b5b2095c5a34b2]*/
5755
0
{
5756
0
    PyObject *self;
5757
0
    if (check_tzinfo_subclass(tzinfo) < 0)
5758
0
        return NULL;
5759
5760
0
    self = datetime_from_timestamp(type,
5761
0
                                   tzinfo == Py_None ? _PyTime_localtime :
5762
0
                                   _PyTime_gmtime,
5763
0
                                   timestamp,
5764
0
                                   tzinfo);
5765
0
    if (self != NULL && tzinfo != Py_None) {
5766
        /* Convert UTC to tzinfo's zone. */
5767
0
        PyObject *res = PyObject_CallMethodOneArg(tzinfo, &_Py_ID(fromutc), self);
5768
0
        Py_DECREF(self);
5769
0
        return res;
5770
0
    }
5771
0
    return self;
5772
0
}
5773
5774
/* This is a wrapper for API compatibility with the public C API. */
5775
static PyObject *
5776
datetime_datetime_fromtimestamp_capi(PyObject *cls, PyObject *args, PyObject *kw)
5777
0
{
5778
0
    PyObject *timestamp;
5779
0
    PyObject *tzinfo = Py_None;
5780
0
    static char *keywords[] = {"timestamp", "tz", NULL};
5781
5782
0
    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
5783
0
                                     keywords, &timestamp, &tzinfo))
5784
0
        return NULL;
5785
0
    return datetime_datetime_fromtimestamp_impl((PyTypeObject *)cls,
5786
0
                                                timestamp, tzinfo);
5787
0
}
5788
5789
/*[clinic input]
5790
@classmethod
5791
datetime.datetime.utcfromtimestamp
5792
5793
    timestamp: object
5794
    /
5795
5796
Create a naive UTC datetime from a POSIX timestamp.
5797
[clinic start generated code]*/
5798
5799
static PyObject *
5800
datetime_datetime_utcfromtimestamp_impl(PyTypeObject *type,
5801
                                        PyObject *timestamp)
5802
/*[clinic end generated code: output=66d0b1741d788fd2 input=13fabd4296b1c206]*/
5803
0
{
5804
0
    if (PyErr_WarnEx(PyExc_DeprecationWarning,
5805
0
        "datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal "
5806
0
        "in a future version. Use timezone-aware objects to represent "
5807
0
        "datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC).", 1))
5808
0
    {
5809
0
        return NULL;
5810
0
    }
5811
5812
0
    return datetime_from_timestamp(type, _PyTime_gmtime, timestamp, Py_None);
5813
0
}
5814
5815
/*[clinic input]
5816
@permit_long_summary
5817
@classmethod
5818
datetime.datetime.strptime
5819
5820
    string: unicode
5821
    format: unicode
5822
    /
5823
5824
Parse string according to the given date and time format (like time.strptime()).
5825
5826
For a list of supported format codes, see the documentation:
5827
    https://docs.python.org/3/library/datetime.html#format-codes
5828
[clinic start generated code]*/
5829
5830
static PyObject *
5831
datetime_datetime_strptime_impl(PyTypeObject *type, PyObject *string,
5832
                                PyObject *format)
5833
/*[clinic end generated code: output=af2c2d024f3203f5 input=ef7807589f1d50e7]*/
5834
0
{
5835
0
    PyObject *result;
5836
5837
0
    PyObject *module = PyImport_Import(&_Py_ID(_strptime));
5838
0
    if (module == NULL) {
5839
0
        return NULL;
5840
0
    }
5841
0
    result = PyObject_CallMethodObjArgs(module,
5842
0
                                        &_Py_ID(_strptime_datetime_datetime),
5843
0
                                        (PyObject *)type, string, format, NULL);
5844
0
    Py_DECREF(module);
5845
0
    return result;
5846
0
}
5847
5848
/*[clinic input]
5849
@classmethod
5850
datetime.datetime.combine
5851
5852
    date: object(subclass_of="DATE_TYPE(NO_STATE)")
5853
    time: object(subclass_of="TIME_TYPE(NO_STATE)")
5854
    tzinfo: object = NULL
5855
5856
Construct a datetime from a given date and a given time.
5857
[clinic start generated code]*/
5858
5859
static PyObject *
5860
datetime_datetime_combine_impl(PyTypeObject *type, PyObject *date,
5861
                               PyObject *time, PyObject *tzinfo)
5862
/*[clinic end generated code: output=a10f3cbb90f4d0aa input=4fcf0743288d0bab]*/
5863
0
{
5864
0
    if (tzinfo == NULL) {
5865
0
        if (HASTZINFO(time))
5866
0
            tzinfo = ((PyDateTime_Time *)time)->tzinfo;
5867
0
        else
5868
0
            tzinfo = Py_None;
5869
0
    }
5870
0
    return new_datetime_subclass_fold_ex(GET_YEAR(date),
5871
0
                                         GET_MONTH(date),
5872
0
                                         GET_DAY(date),
5873
0
                                         TIME_GET_HOUR(time),
5874
0
                                         TIME_GET_MINUTE(time),
5875
0
                                         TIME_GET_SECOND(time),
5876
0
                                         TIME_GET_MICROSECOND(time),
5877
0
                                         tzinfo,
5878
0
                                         TIME_GET_FOLD(time),
5879
0
                                         type);
5880
0
}
5881
5882
static PyObject *
5883
_sanitize_isoformat_str(PyObject *dtstr)
5884
0
{
5885
0
    Py_ssize_t len = PyUnicode_GetLength(dtstr);
5886
0
    if (len < 7) {  // All valid ISO 8601 strings are at least 7 characters long
5887
0
        return NULL;
5888
0
    }
5889
5890
    // `fromisoformat` allows surrogate characters in exactly one position,
5891
    // the separator; to allow datetime_fromisoformat to make the simplifying
5892
    // assumption that all valid strings can be encoded in UTF-8, this function
5893
    // replaces any surrogate character separators with `T`.
5894
    //
5895
    // The result of this, if not NULL, returns a new reference
5896
0
    const void* const unicode_data = PyUnicode_DATA(dtstr);
5897
0
    const int kind = PyUnicode_KIND(dtstr);
5898
5899
    // Depending on the format of the string, the separator can only ever be
5900
    // in positions 7, 8 or 10. We'll check each of these for a surrogate and
5901
    // if we find one, replace it with `T`. If there is more than one surrogate,
5902
    // we don't have to bother sanitizing it, because the function will later
5903
    // fail when we try to encode the string as ASCII.
5904
0
    static const size_t potential_separators[3] = {7, 8, 10};
5905
0
    size_t surrogate_separator = 0;
5906
0
    for(size_t idx = 0;
5907
0
         idx < sizeof(potential_separators) / sizeof(*potential_separators);
5908
0
         ++idx) {
5909
0
        size_t pos = potential_separators[idx];
5910
0
        if (pos > (size_t)len) {
5911
0
            break;
5912
0
        }
5913
5914
0
        if(Py_UNICODE_IS_SURROGATE(PyUnicode_READ(kind, unicode_data, pos))) {
5915
0
            surrogate_separator = pos;
5916
0
            break;
5917
0
        }
5918
0
    }
5919
5920
0
    if (surrogate_separator == 0) {
5921
0
        return Py_NewRef(dtstr);
5922
0
    }
5923
5924
0
    PyObject *str_out = _PyUnicode_Copy(dtstr);
5925
0
    if (str_out == NULL) {
5926
0
        return NULL;
5927
0
    }
5928
5929
0
    if (PyUnicode_WriteChar(str_out, surrogate_separator, (Py_UCS4)'T')) {
5930
0
        Py_DECREF(str_out);
5931
0
        return NULL;
5932
0
    }
5933
5934
0
    return str_out;
5935
0
}
5936
5937
5938
static Py_ssize_t
5939
0
_find_isoformat_datetime_separator(const char *dtstr, Py_ssize_t len) {
5940
    // The valid date formats can all be distinguished by characters 4 and 5
5941
    // and further narrowed down by character
5942
    // which tells us where to look for the separator character.
5943
    // Format    |  As-rendered |   Position
5944
    // ---------------------------------------
5945
    // %Y-%m-%d  |  YYYY-MM-DD  |    10
5946
    // %Y%m%d    |  YYYYMMDD    |     8
5947
    // %Y-W%V    |  YYYY-Www    |     8
5948
    // %YW%V     |  YYYYWww     |     7
5949
    // %Y-W%V-%u |  YYYY-Www-d  |    10
5950
    // %YW%V%u   |  YYYYWwwd    |     8
5951
    // %Y-%j     |  YYYY-DDD    |     8
5952
    // %Y%j      |  YYYYDDD     |     7
5953
    //
5954
    // Note that because we allow *any* character for the separator, in the
5955
    // case where character 4 is W, it's not straightforward to determine where
5956
    // the separator is — in the case of YYYY-Www-d, you have actual ambiguity,
5957
    // e.g. 2020-W01-0000 could be YYYY-Www-D0HH or YYYY-Www-HHMM, when the
5958
    // separator character is a number in the former case or a hyphen in the
5959
    // latter case.
5960
    //
5961
    // The case of YYYYWww can be distinguished from YYYYWwwd by tracking ahead
5962
    // to either the end of the string or the first non-numeric character —
5963
    // since the time components all come in pairs YYYYWww#HH can be
5964
    // distinguished from YYYYWwwd#HH by the fact that there will always be an
5965
    // odd number of digits before the first non-digit character in the former
5966
    // case.
5967
0
    static const char date_separator = '-';
5968
0
    static const char week_indicator = 'W';
5969
5970
0
    if (len == 7) {
5971
0
        return 7;
5972
0
    }
5973
5974
0
    if (dtstr[4] == date_separator) {
5975
        // YYYY-???
5976
5977
0
        if (dtstr[5] == week_indicator) {
5978
            // YYYY-W??
5979
5980
0
            if (len < 8) {
5981
0
                return -1;
5982
0
            }
5983
5984
0
            if (len > 8 && dtstr[8] == date_separator) {
5985
                // YYYY-Www-D (10) or YYYY-Www-HH (8)
5986
0
                if (len == 9) { return -1; }
5987
0
                if (len > 10 && is_digit(dtstr[10])) {
5988
                    // This is as far as we'll try to go to resolve the
5989
                    // ambiguity for the moment — if we have YYYY-Www-##, the
5990
                    // separator is either a hyphen at 8 or a number at 10.
5991
                    //
5992
                    // We'll assume it's a hyphen at 8 because it's way more
5993
                    // likely that someone will use a hyphen as a separator
5994
                    // than a number, but at this point it's really best effort
5995
                    // because this is an extension of the spec anyway.
5996
0
                    return 8;
5997
0
                }
5998
5999
0
                return 10;
6000
0
            } else {
6001
                // YYYY-Www (8)
6002
0
                return 8;
6003
0
            }
6004
0
        } else {
6005
            // YYYY-MM-DD (10)
6006
0
            return 10;
6007
0
        }
6008
0
    } else {
6009
        // YYYY???
6010
0
        if (dtstr[4] == week_indicator) {
6011
            // YYYYWww (7) or YYYYWwwd (8)
6012
0
            size_t idx = 7;
6013
0
            for (; idx < (size_t)len; ++idx) {
6014
                // Keep going until we run out of digits.
6015
0
                if (!is_digit(dtstr[idx])) {
6016
0
                    break;
6017
0
                }
6018
0
            }
6019
6020
0
            if (idx < 9) {
6021
0
                return idx;
6022
0
            }
6023
6024
0
            if (idx % 2 == 0) {
6025
                // If the index of the last number is even, it's YYYYWww
6026
0
                return 7;
6027
0
            } else {
6028
0
                return 8;
6029
0
            }
6030
0
        } else {
6031
            // YYYYMMDD (8)
6032
0
            return 8;
6033
0
        }
6034
0
    }
6035
0
}
6036
6037
/*[clinic input]
6038
@classmethod
6039
datetime.datetime.fromisoformat
6040
6041
    string: unicode
6042
    /
6043
6044
Construct a date from a string in ISO 8601 format.
6045
[clinic start generated code]*/
6046
6047
static PyObject *
6048
datetime_datetime_fromisoformat_impl(PyTypeObject *type, PyObject *string)
6049
/*[clinic end generated code: output=1800a952fcab79d9 input=d517b158209ded42]*/
6050
0
{
6051
    // We only need to sanitize this string if the separator is a surrogate
6052
    // character. In the situation where the separator location is ambiguous,
6053
    // we don't have to sanitize it anything because that can only happen when
6054
    // the separator is either '-' or a number. This should mostly be a noop
6055
    // but it makes the reference counting easier if we still sanitize.
6056
0
    PyObject *dtstr_clean = _sanitize_isoformat_str(string);
6057
0
    if (dtstr_clean == NULL) {
6058
0
        goto invalid_string_error;
6059
0
    }
6060
6061
0
    Py_ssize_t len;
6062
0
    const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
6063
6064
0
    if (dt_ptr == NULL) {
6065
0
        if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
6066
            // Encoding errors are invalid string errors at this point
6067
0
            goto invalid_string_error;
6068
0
        }
6069
0
        else {
6070
0
            goto error;
6071
0
        }
6072
0
    }
6073
6074
0
    const Py_ssize_t separator_location = _find_isoformat_datetime_separator(
6075
0
            dt_ptr, len);
6076
6077
6078
0
    const char *p = dt_ptr;
6079
6080
0
    int year = 0, month = 0, day = 0;
6081
0
    int hour = 0, minute = 0, second = 0, microsecond = 0;
6082
0
    int tzoffset = 0, tzusec = 0;
6083
6084
    // date runs up to separator_location
6085
0
    int rv = parse_isoformat_date(p, separator_location, &year, &month, &day);
6086
6087
0
    if (!rv && len > separator_location) {
6088
        // In UTF-8, the length of multi-byte characters is encoded in the MSB
6089
0
        p += separator_location;
6090
0
        if ((p[0] & 0x80) == 0) {
6091
0
            p += 1;
6092
0
        }
6093
0
        else {
6094
0
            switch (p[0] & 0xf0) {
6095
0
                case 0xe0:
6096
0
                    p += 3;
6097
0
                    break;
6098
0
                case 0xf0:
6099
0
                    p += 4;
6100
0
                    break;
6101
0
                default:
6102
0
                    p += 2;
6103
0
                    break;
6104
0
            }
6105
0
        }
6106
6107
0
        len -= (p - dt_ptr);
6108
0
        rv = parse_isoformat_time(p, len, &hour, &minute, &second,
6109
0
                                  &microsecond, &tzoffset, &tzusec);
6110
0
        if (rv == -6) {
6111
0
            goto error;
6112
0
        }
6113
0
    }
6114
0
    if (rv < 0) {
6115
0
        goto invalid_string_error;
6116
0
    }
6117
6118
0
    PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
6119
0
    if (tzinfo == NULL) {
6120
0
        goto error;
6121
0
    }
6122
6123
0
    if ((hour == 24) && (month <= 12))  {
6124
0
        int d_in_month = days_in_month(year, month);
6125
0
        if (day <= d_in_month) {
6126
0
            if (minute == 0 && second == 0 && microsecond == 0) {
6127
                // Calculate midnight of the next day
6128
0
                hour = 0;
6129
0
                day += 1;
6130
0
                if (day > d_in_month) {
6131
0
                    day = 1;
6132
0
                    month += 1;
6133
0
                    if (month > 12) {
6134
0
                        month = 1;
6135
0
                        year += 1;
6136
0
                    }
6137
0
                }
6138
0
            } else {
6139
0
                goto invalid_iso_midnight;
6140
0
            }
6141
0
        }
6142
0
    }
6143
0
    PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
6144
0
                                            second, microsecond, tzinfo, type);
6145
6146
0
    Py_DECREF(tzinfo);
6147
0
    Py_DECREF(dtstr_clean);
6148
0
    return dt;
6149
6150
0
invalid_iso_midnight:
6151
0
    PyErr_SetString(PyExc_ValueError, "minute, second, and microsecond must be 0 when hour is 24");
6152
0
    Py_DECREF(tzinfo);
6153
0
    Py_DECREF(dtstr_clean);
6154
0
    return NULL;
6155
6156
0
invalid_string_error:
6157
0
    PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", string);
6158
6159
0
error:
6160
0
    Py_XDECREF(dtstr_clean);
6161
6162
0
    return NULL;
6163
0
}
6164
6165
/*
6166
 * Destructor.
6167
 */
6168
6169
static void
6170
datetime_dealloc(PyObject *op)
6171
10.8k
{
6172
10.8k
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6173
10.8k
    if (HASTZINFO(self)) {
6174
22
        Py_XDECREF(self->tzinfo);
6175
22
    }
6176
10.8k
    Py_TYPE(self)->tp_free(self);
6177
10.8k
}
6178
6179
/*
6180
 * Indirect access to tzinfo methods.
6181
 */
6182
6183
/* These are all METH_NOARGS, so don't need to check the arglist. */
6184
static PyObject *
6185
8
datetime_utcoffset(PyObject *op, PyObject *Py_UNUSED(dummy)) {
6186
8
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6187
8
    return call_utcoffset(GET_DT_TZINFO(self), op);
6188
8
}
6189
6190
static PyObject *
6191
0
datetime_dst(PyObject *op, PyObject *Py_UNUSED(dummy)) {
6192
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6193
0
    return call_dst(GET_DT_TZINFO(self), op);
6194
0
}
6195
6196
static PyObject *
6197
0
datetime_tzname(PyObject *op, PyObject *Py_UNUSED(dummy)) {
6198
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6199
0
    return call_tzname(GET_DT_TZINFO(self), op);
6200
0
}
6201
6202
/*
6203
 * datetime arithmetic.
6204
 */
6205
6206
/* factor must be 1 (to add) or -1 (to subtract).  The result inherits
6207
 * the tzinfo state of date.
6208
 */
6209
static PyObject *
6210
add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
6211
                       int factor)
6212
10.7k
{
6213
    /* Note that the C-level additions can't overflow, because of
6214
     * invariant bounds on the member values.
6215
     */
6216
10.7k
    int year = GET_YEAR(date);
6217
10.7k
    int month = GET_MONTH(date);
6218
10.7k
    int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
6219
10.7k
    int hour = DATE_GET_HOUR(date);
6220
10.7k
    int minute = DATE_GET_MINUTE(date);
6221
10.7k
    int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
6222
10.7k
    int microsecond = DATE_GET_MICROSECOND(date) +
6223
10.7k
                      GET_TD_MICROSECONDS(delta) * factor;
6224
6225
10.7k
    assert(factor == 1 || factor == -1);
6226
10.7k
    if (normalize_datetime(&year, &month, &day,
6227
10.7k
                           &hour, &minute, &second, &microsecond) < 0) {
6228
0
        return NULL;
6229
0
    }
6230
6231
10.7k
    return new_datetime_subclass_ex(year, month, day,
6232
10.7k
                                    hour, minute, second, microsecond,
6233
10.7k
                                    HASTZINFO(date) ? date->tzinfo : Py_None,
6234
10.7k
                                    Py_TYPE(date));
6235
10.7k
}
6236
6237
static PyObject *
6238
datetime_add(PyObject *left, PyObject *right)
6239
10.7k
{
6240
10.7k
    if (PyDateTime_Check(left)) {
6241
        /* datetime + ??? */
6242
10.7k
        if (PyDelta_Check(right))
6243
            /* datetime + delta */
6244
10.7k
            return add_datetime_timedelta(
6245
10.7k
                            (PyDateTime_DateTime *)left,
6246
10.7k
                            (PyDateTime_Delta *)right,
6247
10.7k
                            1);
6248
10.7k
    }
6249
0
    else if (PyDelta_Check(left)) {
6250
        /* delta + datetime */
6251
0
        return add_datetime_timedelta((PyDateTime_DateTime *) right,
6252
0
                                      (PyDateTime_Delta *) left,
6253
0
                                      1);
6254
0
    }
6255
10.7k
    Py_RETURN_NOTIMPLEMENTED;
6256
10.7k
}
6257
6258
static PyObject *
6259
datetime_subtract(PyObject *left, PyObject *right)
6260
10
{
6261
10
    PyObject *result = Py_NotImplemented;
6262
6263
10
    if (PyDateTime_Check(left)) {
6264
        /* datetime - ??? */
6265
10
        if (PyDateTime_Check(right)) {
6266
            /* datetime - datetime */
6267
10
            PyObject *offset1, *offset2, *offdiff = NULL;
6268
10
            int delta_d, delta_s, delta_us;
6269
6270
10
            if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
6271
10
                offset1 = Py_NewRef(Py_None);
6272
10
                offset2 = Py_NewRef(Py_None);
6273
10
            }
6274
0
            else {
6275
0
                offset1 = datetime_utcoffset(left, NULL);
6276
0
                if (offset1 == NULL)
6277
0
                    return NULL;
6278
0
                offset2 = datetime_utcoffset(right, NULL);
6279
0
                if (offset2 == NULL) {
6280
0
                    Py_DECREF(offset1);
6281
0
                    return NULL;
6282
0
                }
6283
0
                if ((offset1 != Py_None) != (offset2 != Py_None)) {
6284
0
                    PyErr_SetString(PyExc_TypeError,
6285
0
                                    "can't subtract offset-naive and "
6286
0
                                    "offset-aware datetimes");
6287
0
                    Py_DECREF(offset1);
6288
0
                    Py_DECREF(offset2);
6289
0
                    return NULL;
6290
0
                }
6291
0
            }
6292
10
            if ((offset1 != offset2) &&
6293
0
                delta_cmp(offset1, offset2) != 0) {
6294
0
                offdiff = delta_subtract(offset1, offset2);
6295
0
                if (offdiff == NULL) {
6296
0
                    Py_DECREF(offset1);
6297
0
                    Py_DECREF(offset2);
6298
0
                    return NULL;
6299
0
                }
6300
0
            }
6301
10
            Py_DECREF(offset1);
6302
10
            Py_DECREF(offset2);
6303
10
            delta_d = ymd_to_ord(GET_YEAR(left),
6304
10
                                 GET_MONTH(left),
6305
10
                                 GET_DAY(left)) -
6306
10
                      ymd_to_ord(GET_YEAR(right),
6307
10
                                 GET_MONTH(right),
6308
10
                                 GET_DAY(right));
6309
            /* These can't overflow, since the values are
6310
             * normalized.  At most this gives the number of
6311
             * seconds in one day.
6312
             */
6313
10
            delta_s = (DATE_GET_HOUR(left) -
6314
10
                       DATE_GET_HOUR(right)) * 3600 +
6315
10
                      (DATE_GET_MINUTE(left) -
6316
10
                       DATE_GET_MINUTE(right)) * 60 +
6317
10
                      (DATE_GET_SECOND(left) -
6318
10
                       DATE_GET_SECOND(right));
6319
10
            delta_us = DATE_GET_MICROSECOND(left) -
6320
10
                       DATE_GET_MICROSECOND(right);
6321
10
            result = new_delta(delta_d, delta_s, delta_us, 1);
6322
10
            if (result == NULL)
6323
0
                return NULL;
6324
6325
10
            if (offdiff != NULL) {
6326
0
                Py_SETREF(result, delta_subtract(result, offdiff));
6327
0
                Py_DECREF(offdiff);
6328
0
            }
6329
10
        }
6330
0
        else if (PyDelta_Check(right)) {
6331
            /* datetime - delta */
6332
0
            result = add_datetime_timedelta(
6333
0
                            (PyDateTime_DateTime *)left,
6334
0
                            (PyDateTime_Delta *)right,
6335
0
                            -1);
6336
0
        }
6337
10
    }
6338
6339
10
    if (result == Py_NotImplemented)
6340
0
        Py_INCREF(result);
6341
10
    return result;
6342
10
}
6343
6344
/* Various ways to turn a datetime into a string. */
6345
6346
static PyObject *
6347
datetime_repr(PyObject *op)
6348
0
{
6349
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6350
0
    const char *type_name = Py_TYPE(self)->tp_name;
6351
0
    PyObject *baserepr;
6352
6353
0
    if (DATE_GET_MICROSECOND(self)) {
6354
0
        baserepr = PyUnicode_FromFormat(
6355
0
                      "%s(%d, %d, %d, %d, %d, %d, %d)",
6356
0
                      type_name,
6357
0
                      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
6358
0
                      DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
6359
0
                      DATE_GET_SECOND(self),
6360
0
                      DATE_GET_MICROSECOND(self));
6361
0
    }
6362
0
    else if (DATE_GET_SECOND(self)) {
6363
0
        baserepr = PyUnicode_FromFormat(
6364
0
                      "%s(%d, %d, %d, %d, %d, %d)",
6365
0
                      type_name,
6366
0
                      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
6367
0
                      DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
6368
0
                      DATE_GET_SECOND(self));
6369
0
    }
6370
0
    else {
6371
0
        baserepr = PyUnicode_FromFormat(
6372
0
                      "%s(%d, %d, %d, %d, %d)",
6373
0
                      type_name,
6374
0
                      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
6375
0
                      DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
6376
0
    }
6377
0
    if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
6378
0
        baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
6379
0
    if (baserepr == NULL || ! HASTZINFO(self))
6380
0
        return baserepr;
6381
0
    return append_keyword_tzinfo(baserepr, self->tzinfo);
6382
0
}
6383
6384
static PyObject *
6385
datetime_str(PyObject *op)
6386
0
{
6387
0
    PyObject *space = PyUnicode_FromString(" ");
6388
0
    if (space == NULL) {
6389
0
        return NULL;
6390
0
    }
6391
0
    PyObject *res = PyObject_CallMethodOneArg(op, &_Py_ID(isoformat), space);
6392
0
    Py_DECREF(space);
6393
0
    return res;
6394
0
}
6395
6396
/*[clinic input]
6397
datetime.datetime.isoformat
6398
6399
    sep: int(accept={str}) = 'T'
6400
    timespec: str(c_default="NULL") = 'auto'
6401
6402
Return the time formatted according to ISO.
6403
6404
The full format looks like 'YYYY-MM-DD HH:MM:SS.mmmmmm'.
6405
By default, the fractional part is omitted if self.microsecond == 0.
6406
6407
If self.tzinfo is not None, the UTC offset is also attached, giving
6408
a full format of 'YYYY-MM-DD HH:MM:SS.mmmmmm+HH:MM'.
6409
6410
Optional argument sep specifies the separator between date and
6411
time, default 'T'.
6412
6413
The optional argument timespec specifies the number of additional
6414
terms of the time to include. Valid options are 'auto', 'hours',
6415
'minutes', 'seconds', 'milliseconds' and 'microseconds'.
6416
[clinic start generated code]*/
6417
6418
static PyObject *
6419
datetime_datetime_isoformat_impl(PyDateTime_DateTime *self, int sep,
6420
                                 const char *timespec)
6421
/*[clinic end generated code: output=9b6ce1383189b0bf input=db935a57fa697c5e]*/
6422
0
{
6423
0
    char buffer[100];
6424
6425
0
    PyObject *result = NULL;
6426
0
    int us = DATE_GET_MICROSECOND(self);
6427
0
    static const char * const specs[][2] = {
6428
0
        {"hours", "%04d-%02d-%02d%c%02d"},
6429
0
        {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
6430
0
        {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
6431
0
        {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
6432
0
        {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
6433
0
    };
6434
0
    size_t given_spec;
6435
6436
0
    if (timespec == NULL || strcmp(timespec, "auto") == 0) {
6437
0
        if (us == 0) {
6438
            /* seconds */
6439
0
            given_spec = 2;
6440
0
        }
6441
0
        else {
6442
            /* microseconds */
6443
0
            given_spec = 4;
6444
0
        }
6445
0
    }
6446
0
    else {
6447
0
        for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
6448
0
            if (strcmp(timespec, specs[given_spec][0]) == 0) {
6449
0
                if (given_spec == 3) {
6450
0
                    us = us / 1000;
6451
0
                }
6452
0
                break;
6453
0
            }
6454
0
        }
6455
0
    }
6456
6457
0
    if (given_spec == Py_ARRAY_LENGTH(specs)) {
6458
0
        PyErr_Format(PyExc_ValueError, "Unknown timespec value");
6459
0
        return NULL;
6460
0
    }
6461
0
    else {
6462
0
        result = PyUnicode_FromFormat(specs[given_spec][1],
6463
0
                                      GET_YEAR(self), GET_MONTH(self),
6464
0
                                      GET_DAY(self), (int)sep,
6465
0
                                      DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
6466
0
                                      DATE_GET_SECOND(self), us);
6467
0
    }
6468
6469
0
    if (!result || !HASTZINFO(self))
6470
0
        return result;
6471
6472
    /* We need to append the UTC offset. */
6473
0
    if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo, (PyObject *)self) < 0) {
6474
0
        Py_DECREF(result);
6475
0
        return NULL;
6476
0
    }
6477
0
    PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
6478
0
    return result;
6479
0
}
6480
6481
static PyObject *
6482
datetime_ctime(PyObject *op, PyObject *Py_UNUSED(dummy))
6483
0
{
6484
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6485
0
    return format_ctime(op,
6486
0
                        DATE_GET_HOUR(self),
6487
0
                        DATE_GET_MINUTE(self),
6488
0
                        DATE_GET_SECOND(self));
6489
0
}
6490
6491
/* Miscellaneous methods. */
6492
6493
static PyObject *
6494
flip_fold(PyObject *dt)
6495
0
{
6496
0
    return new_datetime_ex2(GET_YEAR(dt),
6497
0
                            GET_MONTH(dt),
6498
0
                            GET_DAY(dt),
6499
0
                            DATE_GET_HOUR(dt),
6500
0
                            DATE_GET_MINUTE(dt),
6501
0
                            DATE_GET_SECOND(dt),
6502
0
                            DATE_GET_MICROSECOND(dt),
6503
0
                            HASTZINFO(dt) ?
6504
0
                             ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
6505
0
                            !DATE_GET_FOLD(dt),
6506
0
                            Py_TYPE(dt));
6507
0
}
6508
6509
static PyObject *
6510
get_flip_fold_offset(PyObject *dt)
6511
0
{
6512
0
    PyObject *result, *flip_dt;
6513
6514
0
    flip_dt = flip_fold(dt);
6515
0
    if (flip_dt == NULL)
6516
0
        return NULL;
6517
0
    result = datetime_utcoffset(flip_dt, NULL);
6518
0
    Py_DECREF(flip_dt);
6519
0
    return result;
6520
0
}
6521
6522
/* PEP 495 exception: Whenever one or both of the operands in
6523
 * inter-zone comparison is such that its utcoffset() depends
6524
 * on the value of its fold attribute, the result is False.
6525
 *
6526
 * Return 1 if exception applies, 0 if not,  and -1 on error.
6527
 */
6528
static int
6529
pep495_eq_exception(PyObject *self, PyObject *other,
6530
                    PyObject *offset_self, PyObject *offset_other)
6531
0
{
6532
0
    int result = 0;
6533
0
    PyObject *flip_offset;
6534
6535
0
    flip_offset = get_flip_fold_offset(self);
6536
0
    if (flip_offset == NULL)
6537
0
        return -1;
6538
0
    if (flip_offset != offset_self &&
6539
0
        delta_cmp(flip_offset, offset_self))
6540
0
    {
6541
0
        result = 1;
6542
0
        goto done;
6543
0
    }
6544
0
    Py_DECREF(flip_offset);
6545
6546
0
    flip_offset = get_flip_fold_offset(other);
6547
0
    if (flip_offset == NULL)
6548
0
        return -1;
6549
0
    if (flip_offset != offset_other &&
6550
0
        delta_cmp(flip_offset, offset_other))
6551
0
        result = 1;
6552
0
 done:
6553
0
    Py_DECREF(flip_offset);
6554
0
    return result;
6555
0
}
6556
6557
static PyObject *
6558
datetime_richcompare(PyObject *self, PyObject *other, int op)
6559
0
{
6560
0
    PyObject *result = NULL;
6561
0
    PyObject *offset1, *offset2;
6562
0
    int diff;
6563
6564
0
    if (!PyDateTime_Check(other)) {
6565
0
        Py_RETURN_NOTIMPLEMENTED;
6566
0
    }
6567
6568
0
    if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
6569
0
        diff = memcmp(((PyDateTime_DateTime *)self)->data,
6570
0
                      ((PyDateTime_DateTime *)other)->data,
6571
0
                      _PyDateTime_DATETIME_DATASIZE);
6572
0
        return diff_to_bool(diff, op);
6573
0
    }
6574
0
    offset1 = datetime_utcoffset(self, NULL);
6575
0
    if (offset1 == NULL)
6576
0
        return NULL;
6577
0
    offset2 = datetime_utcoffset(other, NULL);
6578
0
    if (offset2 == NULL)
6579
0
        goto done;
6580
    /* If they're both naive, or both aware and have the same offsets,
6581
     * we get off cheap.  Note that if they're both naive, offset1 ==
6582
     * offset2 == Py_None at this point.
6583
     */
6584
0
    if ((offset1 == offset2) ||
6585
0
        (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
6586
0
         delta_cmp(offset1, offset2) == 0)) {
6587
0
        diff = memcmp(((PyDateTime_DateTime *)self)->data,
6588
0
                      ((PyDateTime_DateTime *)other)->data,
6589
0
                      _PyDateTime_DATETIME_DATASIZE);
6590
0
        if ((op == Py_EQ || op == Py_NE) && diff == 0) {
6591
0
            int ex = pep495_eq_exception(self, other, offset1, offset2);
6592
0
            if (ex == -1)
6593
0
                goto done;
6594
0
            if (ex)
6595
0
                diff = 1;
6596
0
        }
6597
0
        result = diff_to_bool(diff, op);
6598
0
    }
6599
0
    else if (offset1 != Py_None && offset2 != Py_None) {
6600
0
        PyDateTime_Delta *delta;
6601
6602
0
        assert(offset1 != offset2); /* else last "if" handled it */
6603
0
        delta = (PyDateTime_Delta *)datetime_subtract(self, other);
6604
0
        if (delta == NULL)
6605
0
            goto done;
6606
0
        diff = GET_TD_DAYS(delta);
6607
0
        if (diff == 0)
6608
0
            diff = GET_TD_SECONDS(delta) |
6609
0
                   GET_TD_MICROSECONDS(delta);
6610
0
        Py_DECREF(delta);
6611
0
        if ((op == Py_EQ || op == Py_NE) && diff == 0) {
6612
0
            int ex = pep495_eq_exception(self, other, offset1, offset2);
6613
0
            if (ex == -1)
6614
0
                goto done;
6615
0
            if (ex)
6616
0
                diff = 1;
6617
0
        }
6618
0
        result = diff_to_bool(diff, op);
6619
0
    }
6620
0
    else if (op == Py_EQ) {
6621
0
        result = Py_NewRef(Py_False);
6622
0
    }
6623
0
    else if (op == Py_NE) {
6624
0
        result = Py_NewRef(Py_True);
6625
0
    }
6626
0
    else {
6627
0
        PyErr_SetString(PyExc_TypeError,
6628
0
                        "can't compare offset-naive and "
6629
0
                        "offset-aware datetimes");
6630
0
    }
6631
0
 done:
6632
0
    Py_DECREF(offset1);
6633
0
    Py_XDECREF(offset2);
6634
0
    return result;
6635
0
}
6636
6637
static Py_hash_t
6638
datetime_hash(PyObject *op)
6639
32
{
6640
32
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6641
32
    Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
6642
32
    if (hash == -1) {
6643
8
        PyObject *offset, *self0;
6644
8
        if (DATE_GET_FOLD(self)) {
6645
0
            self0 = new_datetime_ex2(GET_YEAR(self),
6646
0
                                     GET_MONTH(self),
6647
0
                                     GET_DAY(self),
6648
0
                                     DATE_GET_HOUR(self),
6649
0
                                     DATE_GET_MINUTE(self),
6650
0
                                     DATE_GET_SECOND(self),
6651
0
                                     DATE_GET_MICROSECOND(self),
6652
0
                                     HASTZINFO(self) ? self->tzinfo : Py_None,
6653
0
                                     0, Py_TYPE(self));
6654
0
            if (self0 == NULL)
6655
0
                return -1;
6656
0
        }
6657
8
        else {
6658
8
            self0 = Py_NewRef(self);
6659
8
        }
6660
8
        offset = datetime_utcoffset(self0, NULL);
6661
8
        Py_DECREF(self0);
6662
6663
8
        if (offset == NULL)
6664
0
            return -1;
6665
6666
        /* Reduce this to a hash of another object. */
6667
8
        if (offset == Py_None) {
6668
8
            hash = generic_hash(
6669
8
                (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
6670
8
            FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
6671
8
        } else {
6672
0
            PyObject *temp1, *temp2;
6673
0
            int days, seconds;
6674
6675
0
            assert(HASTZINFO(self));
6676
0
            days = ymd_to_ord(GET_YEAR(self),
6677
0
                              GET_MONTH(self),
6678
0
                              GET_DAY(self));
6679
0
            seconds = DATE_GET_HOUR(self) * 3600 +
6680
0
                      DATE_GET_MINUTE(self) * 60 +
6681
0
                      DATE_GET_SECOND(self);
6682
0
            temp1 = new_delta(days, seconds,
6683
0
                              DATE_GET_MICROSECOND(self),
6684
0
                              1);
6685
0
            if (temp1 == NULL) {
6686
0
                Py_DECREF(offset);
6687
0
                return -1;
6688
0
            }
6689
0
            temp2 = delta_subtract(temp1, offset);
6690
0
            Py_DECREF(temp1);
6691
0
            if (temp2 == NULL) {
6692
0
                Py_DECREF(offset);
6693
0
                return -1;
6694
0
            }
6695
0
            hash = PyObject_Hash(temp2);
6696
0
            FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
6697
0
            Py_DECREF(temp2);
6698
0
        }
6699
8
        Py_DECREF(offset);
6700
8
    }
6701
32
    return hash;
6702
32
}
6703
6704
/*[clinic input]
6705
datetime.datetime.replace
6706
6707
    year: int(c_default="GET_YEAR(self)") = unchanged
6708
    month: int(c_default="GET_MONTH(self)") = unchanged
6709
    day: int(c_default="GET_DAY(self)") = unchanged
6710
    hour: int(c_default="DATE_GET_HOUR(self)") = unchanged
6711
    minute: int(c_default="DATE_GET_MINUTE(self)") = unchanged
6712
    second: int(c_default="DATE_GET_SECOND(self)") = unchanged
6713
    microsecond: int(c_default="DATE_GET_MICROSECOND(self)") = unchanged
6714
    tzinfo: object(c_default="HASTZINFO(self) ? ((PyDateTime_DateTime *)self)->tzinfo : Py_None") = unchanged
6715
    *
6716
    fold: int(c_default="DATE_GET_FOLD(self)") = unchanged
6717
6718
Return datetime with new specified fields.
6719
[clinic start generated code]*/
6720
6721
static PyObject *
6722
datetime_datetime_replace_impl(PyDateTime_DateTime *self, int year,
6723
                               int month, int day, int hour, int minute,
6724
                               int second, int microsecond, PyObject *tzinfo,
6725
                               int fold)
6726
/*[clinic end generated code: output=00bc96536833fddb input=fd972762d604d3e7]*/
6727
0
{
6728
0
    return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
6729
0
                                         second, microsecond, tzinfo, fold,
6730
0
                                         Py_TYPE(self));
6731
0
}
6732
6733
static PyObject *
6734
local_timezone_from_timestamp(time_t timestamp)
6735
0
{
6736
0
    PyObject *result = NULL;
6737
0
    PyObject *delta;
6738
0
    struct tm local_time_tm;
6739
0
    PyObject *nameo = NULL;
6740
0
    const char *zone = NULL;
6741
6742
0
    if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
6743
0
        return NULL;
6744
0
#ifdef HAVE_STRUCT_TM_TM_ZONE
6745
0
    zone = local_time_tm.tm_zone;
6746
0
    delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
6747
#else /* HAVE_STRUCT_TM_TM_ZONE */
6748
    {
6749
        PyObject *local_time, *utc_time;
6750
        struct tm utc_time_tm;
6751
        char buf[100];
6752
        strftime(buf, sizeof(buf), "%Z", &local_time_tm);
6753
        zone = buf;
6754
        local_time = new_datetime(local_time_tm.tm_year + 1900,
6755
                                  local_time_tm.tm_mon + 1,
6756
                                  local_time_tm.tm_mday,
6757
                                  local_time_tm.tm_hour,
6758
                                  local_time_tm.tm_min,
6759
                                  local_time_tm.tm_sec, 0, Py_None, 0);
6760
        if (local_time == NULL) {
6761
            return NULL;
6762
        }
6763
        if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
6764
            return NULL;
6765
        utc_time = new_datetime(utc_time_tm.tm_year + 1900,
6766
                                utc_time_tm.tm_mon + 1,
6767
                                utc_time_tm.tm_mday,
6768
                                utc_time_tm.tm_hour,
6769
                                utc_time_tm.tm_min,
6770
                                utc_time_tm.tm_sec, 0, Py_None, 0);
6771
        if (utc_time == NULL) {
6772
            Py_DECREF(local_time);
6773
            return NULL;
6774
        }
6775
        delta = datetime_subtract(local_time, utc_time);
6776
        Py_DECREF(local_time);
6777
        Py_DECREF(utc_time);
6778
    }
6779
#endif /* HAVE_STRUCT_TM_TM_ZONE */
6780
0
    if (delta == NULL) {
6781
0
            return NULL;
6782
0
    }
6783
0
    if (zone != NULL) {
6784
0
        nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
6785
0
        if (nameo == NULL)
6786
0
            goto error;
6787
0
    }
6788
0
    result = new_timezone(delta, nameo);
6789
0
    Py_XDECREF(nameo);
6790
0
  error:
6791
0
    Py_DECREF(delta);
6792
0
    return result;
6793
0
}
6794
6795
static PyObject *
6796
local_timezone(PyDateTime_DateTime *utc_time)
6797
0
{
6798
0
    time_t timestamp;
6799
0
    PyObject *delta;
6800
0
    PyObject *one_second;
6801
0
    PyObject *seconds;
6802
6803
0
    PyObject *current_mod = NULL;
6804
0
    datetime_state *st = GET_CURRENT_STATE(current_mod);
6805
6806
0
    delta = datetime_subtract((PyObject *)utc_time, CONST_EPOCH(st));
6807
0
    RELEASE_CURRENT_STATE(st, current_mod);
6808
0
    if (delta == NULL)
6809
0
        return NULL;
6810
6811
0
    one_second = new_delta(0, 1, 0, 0);
6812
0
    if (one_second == NULL) {
6813
0
        Py_DECREF(delta);
6814
0
        return NULL;
6815
0
    }
6816
0
    seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
6817
0
                                         (PyDateTime_Delta *)one_second);
6818
0
    Py_DECREF(one_second);
6819
0
    Py_DECREF(delta);
6820
0
    if (seconds == NULL)
6821
0
        return NULL;
6822
0
    timestamp = _PyLong_AsTime_t(seconds);
6823
0
    Py_DECREF(seconds);
6824
0
    if (timestamp == -1 && PyErr_Occurred())
6825
0
        return NULL;
6826
0
    return local_timezone_from_timestamp(timestamp);
6827
0
}
6828
6829
static long long
6830
local_to_seconds(int year, int month, int day,
6831
                 int hour, int minute, int second, int fold);
6832
6833
static PyObject *
6834
local_timezone_from_local(PyDateTime_DateTime *local_dt)
6835
0
{
6836
0
    long long seconds, seconds2;
6837
0
    time_t timestamp;
6838
0
    int fold = DATE_GET_FOLD(local_dt);
6839
0
    seconds = local_to_seconds(GET_YEAR(local_dt),
6840
0
                               GET_MONTH(local_dt),
6841
0
                               GET_DAY(local_dt),
6842
0
                               DATE_GET_HOUR(local_dt),
6843
0
                               DATE_GET_MINUTE(local_dt),
6844
0
                               DATE_GET_SECOND(local_dt),
6845
0
                               fold);
6846
0
    if (seconds == -1)
6847
0
        return NULL;
6848
0
    seconds2 = local_to_seconds(GET_YEAR(local_dt),
6849
0
                                GET_MONTH(local_dt),
6850
0
                                GET_DAY(local_dt),
6851
0
                                DATE_GET_HOUR(local_dt),
6852
0
                                DATE_GET_MINUTE(local_dt),
6853
0
                                DATE_GET_SECOND(local_dt),
6854
0
                                !fold);
6855
0
    if (seconds2 == -1)
6856
0
        return NULL;
6857
    /* Detect gap */
6858
0
    if (seconds2 != seconds && (seconds2 > seconds) == fold)
6859
0
        seconds = seconds2;
6860
6861
    /* XXX: add bounds check */
6862
0
    timestamp = seconds - epoch;
6863
0
    return local_timezone_from_timestamp(timestamp);
6864
0
}
6865
6866
/*[clinic input]
6867
datetime.datetime.astimezone
6868
6869
    tz as tzinfo: object = None
6870
6871
Convert to local time in new timezone tz.
6872
[clinic start generated code]*/
6873
6874
static PyObject *
6875
datetime_datetime_astimezone_impl(PyDateTime_DateTime *self,
6876
                                  PyObject *tzinfo)
6877
/*[clinic end generated code: output=ae2263d04e944537 input=9c675c8595009935]*/
6878
0
{
6879
0
    PyDateTime_DateTime *result;
6880
0
    PyObject *offset;
6881
0
    PyObject *temp;
6882
0
    PyObject *self_tzinfo;
6883
6884
0
    if (check_tzinfo_subclass(tzinfo) == -1)
6885
0
        return NULL;
6886
6887
0
    if (!HASTZINFO(self) || self->tzinfo == Py_None) {
6888
0
  naive:
6889
0
        self_tzinfo = local_timezone_from_local(self);
6890
0
        if (self_tzinfo == NULL)
6891
0
            return NULL;
6892
0
    } else {
6893
0
        self_tzinfo = Py_NewRef(self->tzinfo);
6894
0
    }
6895
6896
    /* Conversion to self's own time zone is a NOP. */
6897
0
    if (self_tzinfo == tzinfo) {
6898
0
        Py_DECREF(self_tzinfo);
6899
0
        return Py_NewRef(self);
6900
0
    }
6901
6902
    /* Convert self to UTC. */
6903
0
    offset = call_utcoffset(self_tzinfo, (PyObject *)self);
6904
0
    Py_DECREF(self_tzinfo);
6905
0
    if (offset == NULL)
6906
0
        return NULL;
6907
0
    else if(offset == Py_None) {
6908
0
        Py_DECREF(offset);
6909
0
        goto naive;
6910
0
    }
6911
0
    else if (!PyDelta_Check(offset)) {
6912
0
        PyErr_Format(PyExc_TypeError, "utcoffset() returned %T,"
6913
0
                     " expected timedelta or None", offset);
6914
0
        Py_DECREF(offset);
6915
0
        return NULL;
6916
0
    }
6917
    /* result = self - offset */
6918
0
    result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6919
0
                                       (PyDateTime_Delta *)offset, -1);
6920
0
    Py_DECREF(offset);
6921
0
    if (result == NULL)
6922
0
        return NULL;
6923
6924
    /* Make sure result is aware and UTC. */
6925
0
    if (!HASTZINFO(result)) {
6926
0
        temp = (PyObject *)result;
6927
0
        result = (PyDateTime_DateTime *)
6928
0
                   new_datetime_ex2(GET_YEAR(result),
6929
0
                                    GET_MONTH(result),
6930
0
                                    GET_DAY(result),
6931
0
                                    DATE_GET_HOUR(result),
6932
0
                                    DATE_GET_MINUTE(result),
6933
0
                                    DATE_GET_SECOND(result),
6934
0
                                    DATE_GET_MICROSECOND(result),
6935
0
                                    CONST_UTC(NO_STATE),
6936
0
                                    DATE_GET_FOLD(result),
6937
0
                                    Py_TYPE(result));
6938
0
        Py_DECREF(temp);
6939
0
        if (result == NULL)
6940
0
            return NULL;
6941
0
    }
6942
0
    else {
6943
        /* Result is already aware - just replace tzinfo. */
6944
0
        Py_SETREF(result->tzinfo, Py_NewRef(CONST_UTC(NO_STATE)));
6945
0
    }
6946
6947
    /* Attach new tzinfo and let fromutc() do the rest. */
6948
0
    if (tzinfo == Py_None) {
6949
0
        tzinfo = local_timezone(result);
6950
0
        if (tzinfo == NULL) {
6951
0
            Py_DECREF(result);
6952
0
            return NULL;
6953
0
        }
6954
0
    }
6955
0
    else
6956
0
      Py_INCREF(tzinfo);
6957
0
    Py_SETREF(result->tzinfo, tzinfo);
6958
6959
0
    temp = (PyObject *)result;
6960
0
    result = (PyDateTime_DateTime *)
6961
0
        PyObject_CallMethodOneArg(tzinfo, &_Py_ID(fromutc), temp);
6962
0
    Py_DECREF(temp);
6963
6964
0
    return (PyObject *)result;
6965
0
}
6966
6967
static PyObject *
6968
datetime_timetuple(PyObject *op, PyObject *Py_UNUSED(dummy))
6969
10.7k
{
6970
10.7k
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6971
10.7k
    int dstflag = -1;
6972
6973
10.7k
    if (HASTZINFO(self) && self->tzinfo != Py_None) {
6974
0
        PyObject * dst;
6975
6976
0
        dst = call_dst(self->tzinfo, op);
6977
0
        if (dst == NULL)
6978
0
            return NULL;
6979
6980
0
        if (dst != Py_None)
6981
0
            dstflag = delta_bool(dst);
6982
0
        Py_DECREF(dst);
6983
0
    }
6984
10.7k
    return build_struct_time(GET_YEAR(self),
6985
10.7k
                             GET_MONTH(self),
6986
10.7k
                             GET_DAY(self),
6987
10.7k
                             DATE_GET_HOUR(self),
6988
10.7k
                             DATE_GET_MINUTE(self),
6989
10.7k
                             DATE_GET_SECOND(self),
6990
10.7k
                             dstflag);
6991
10.7k
}
6992
6993
static long long
6994
local_to_seconds(int year, int month, int day,
6995
                 int hour, int minute, int second, int fold)
6996
0
{
6997
0
    long long t, a, b, u1, u2, t1, t2, lt;
6998
0
    t = utc_to_seconds(year, month, day, hour, minute, second);
6999
    /* Our goal is to solve t = local(u) for u. */
7000
0
    lt = local(t);
7001
0
    if (lt == -1)
7002
0
        return -1;
7003
0
    a = lt - t;
7004
0
    u1 = t - a;
7005
0
    t1 = local(u1);
7006
0
    if (t1 == -1)
7007
0
        return -1;
7008
0
    if (t1 == t) {
7009
        /* We found one solution, but it may not be the one we need.
7010
         * Look for an earlier solution (if `fold` is 0), or a
7011
         * later one (if `fold` is 1). */
7012
0
        if (fold)
7013
0
            u2 = u1 + max_fold_seconds;
7014
0
        else
7015
0
            u2 = u1 - max_fold_seconds;
7016
0
        lt = local(u2);
7017
0
        if (lt == -1)
7018
0
            return -1;
7019
0
        b = lt - u2;
7020
0
        if (a == b)
7021
0
            return u1;
7022
0
    }
7023
0
    else {
7024
0
        b = t1 - u1;
7025
0
        assert(a != b);
7026
0
    }
7027
0
    u2 = t - b;
7028
0
    t2 = local(u2);
7029
0
    if (t2 == -1)
7030
0
        return -1;
7031
0
    if (t2 == t)
7032
0
        return u2;
7033
0
    if (t1 == t)
7034
0
        return u1;
7035
    /* We have found both offsets a and b, but neither t - a nor t - b is
7036
     * a solution.  This means t is in the gap. */
7037
0
    return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
7038
0
}
7039
7040
/* date(1970,1,1).toordinal() == 719163 */
7041
0
#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
7042
7043
static PyObject *
7044
datetime_timestamp(PyObject *op, PyObject *Py_UNUSED(dummy))
7045
0
{
7046
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
7047
0
    PyObject *result;
7048
7049
0
    if (HASTZINFO(self) && self->tzinfo != Py_None) {
7050
0
        PyObject *current_mod = NULL;
7051
0
        datetime_state *st = GET_CURRENT_STATE(current_mod);
7052
7053
0
        PyObject *delta;
7054
0
        delta = datetime_subtract(op, CONST_EPOCH(st));
7055
0
        RELEASE_CURRENT_STATE(st, current_mod);
7056
0
        if (delta == NULL)
7057
0
            return NULL;
7058
0
        result = delta_total_seconds(delta, NULL);
7059
0
        Py_DECREF(delta);
7060
0
    }
7061
0
    else {
7062
0
        long long seconds;
7063
0
        seconds = local_to_seconds(GET_YEAR(self),
7064
0
                                   GET_MONTH(self),
7065
0
                                   GET_DAY(self),
7066
0
                                   DATE_GET_HOUR(self),
7067
0
                                   DATE_GET_MINUTE(self),
7068
0
                                   DATE_GET_SECOND(self),
7069
0
                                   DATE_GET_FOLD(self));
7070
0
        if (seconds == -1)
7071
0
            return NULL;
7072
0
        result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
7073
0
                                    DATE_GET_MICROSECOND(self) / 1e6);
7074
0
    }
7075
0
    return result;
7076
0
}
7077
7078
static PyObject *
7079
datetime_getdate(PyObject *op, PyObject *Py_UNUSED(dummy))
7080
0
{
7081
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
7082
0
    return new_date(GET_YEAR(self),
7083
0
                    GET_MONTH(self),
7084
0
                    GET_DAY(self));
7085
0
}
7086
7087
static PyObject *
7088
datetime_gettime(PyObject *op, PyObject *Py_UNUSED(dummy))
7089
0
{
7090
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
7091
0
    return new_time(DATE_GET_HOUR(self),
7092
0
                    DATE_GET_MINUTE(self),
7093
0
                    DATE_GET_SECOND(self),
7094
0
                    DATE_GET_MICROSECOND(self),
7095
0
                    Py_None,
7096
0
                    DATE_GET_FOLD(self));
7097
0
}
7098
7099
static PyObject *
7100
datetime_gettimetz(PyObject *op, PyObject *Py_UNUSED(dummy))
7101
0
{
7102
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
7103
0
    return new_time(DATE_GET_HOUR(self),
7104
0
                    DATE_GET_MINUTE(self),
7105
0
                    DATE_GET_SECOND(self),
7106
0
                    DATE_GET_MICROSECOND(self),
7107
0
                    GET_DT_TZINFO(self),
7108
0
                    DATE_GET_FOLD(self));
7109
0
}
7110
7111
static PyObject *
7112
datetime_utctimetuple(PyObject *op, PyObject *Py_UNUSED(dummy))
7113
0
{
7114
0
    int y, m, d, hh, mm, ss;
7115
0
    PyObject *tzinfo;
7116
0
    PyDateTime_DateTime *utcself;
7117
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
7118
7119
0
    tzinfo = GET_DT_TZINFO(self);
7120
0
    if (tzinfo == Py_None) {
7121
0
        utcself = (PyDateTime_DateTime*)Py_NewRef(self);
7122
0
    }
7123
0
    else {
7124
0
        PyObject *offset;
7125
0
        offset = call_utcoffset(tzinfo, (PyObject *)self);
7126
0
        if (offset == NULL)
7127
0
            return NULL;
7128
0
        if (offset == Py_None) {
7129
0
            Py_DECREF(offset);
7130
0
            utcself = (PyDateTime_DateTime*)Py_NewRef(self);
7131
0
        }
7132
0
        else {
7133
0
            utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
7134
0
                                                (PyDateTime_Delta *)offset, -1);
7135
0
            Py_DECREF(offset);
7136
0
            if (utcself == NULL)
7137
0
                return NULL;
7138
0
        }
7139
0
    }
7140
0
    y = GET_YEAR(utcself);
7141
0
    m = GET_MONTH(utcself);
7142
0
    d = GET_DAY(utcself);
7143
0
    hh = DATE_GET_HOUR(utcself);
7144
0
    mm = DATE_GET_MINUTE(utcself);
7145
0
    ss = DATE_GET_SECOND(utcself);
7146
7147
0
    Py_DECREF(utcself);
7148
0
    return build_struct_time(y, m, d, hh, mm, ss, 0);
7149
0
}
7150
7151
/* Pickle support, a simple use of __reduce__. */
7152
7153
/* Let basestate be the non-tzinfo data string.
7154
 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
7155
 * So it's a tuple in any (non-error) case.
7156
 * __getstate__ isn't exposed.
7157
 */
7158
static PyObject *
7159
datetime_getstate(PyDateTime_DateTime *self, int proto)
7160
0
{
7161
0
    PyObject *basestate;
7162
0
    PyObject *result = NULL;
7163
7164
0
    basestate = PyBytes_FromStringAndSize((char *)self->data,
7165
0
                                           _PyDateTime_DATETIME_DATASIZE);
7166
0
    if (basestate != NULL) {
7167
0
        if (proto > 3 && DATE_GET_FOLD(self))
7168
            /* Set the first bit of the third byte */
7169
0
            PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
7170
0
        if (! HASTZINFO(self) || self->tzinfo == Py_None)
7171
0
            result = PyTuple_Pack(1, basestate);
7172
0
        else
7173
0
            result = _PyTuple_FromPair(basestate, self->tzinfo);
7174
0
        Py_DECREF(basestate);
7175
0
    }
7176
0
    return result;
7177
0
}
7178
7179
/*[clinic input]
7180
datetime.datetime.__reduce_ex__
7181
7182
    proto: int
7183
    /
7184
[clinic start generated code]*/
7185
7186
static PyObject *
7187
datetime_datetime___reduce_ex___impl(PyDateTime_DateTime *self, int proto)
7188
/*[clinic end generated code: output=53d712ce3e927735 input=bab748e49ffb30c3]*/
7189
0
{
7190
0
    return Py_BuildValue("(ON)", Py_TYPE(self),
7191
0
                         datetime_getstate(self, proto));
7192
0
}
7193
7194
/*[clinic input]
7195
datetime.datetime.__reduce__
7196
[clinic start generated code]*/
7197
7198
static PyObject *
7199
datetime_datetime___reduce___impl(PyDateTime_DateTime *self)
7200
/*[clinic end generated code: output=6794df9ea75666cf input=cadbbeb3bf3bf94c]*/
7201
0
{
7202
0
    return Py_BuildValue("(ON)", Py_TYPE(self),
7203
0
                         datetime_getstate(self, 2));
7204
0
}
7205
7206
static PyMethodDef datetime_methods[] = {
7207
7208
    /* Class methods: */
7209
7210
    DATETIME_DATETIME_NOW_METHODDEF
7211
    DATETIME_DATETIME_UTCNOW_METHODDEF
7212
    DATETIME_DATETIME_FROMTIMESTAMP_METHODDEF
7213
    DATETIME_DATETIME_UTCFROMTIMESTAMP_METHODDEF
7214
    DATETIME_DATETIME_STRPTIME_METHODDEF
7215
    DATETIME_DATETIME_COMBINE_METHODDEF
7216
    DATETIME_DATETIME_FROMISOFORMAT_METHODDEF
7217
7218
    /* Instance methods: */
7219
7220
    {"date", datetime_getdate, METH_NOARGS,
7221
     PyDoc_STR("Return date object with same year, month and day.")},
7222
7223
    {"time", datetime_gettime, METH_NOARGS,
7224
     PyDoc_STR("Return time object with same time but with tzinfo=None.")},
7225
7226
    {"timetz", datetime_gettimetz, METH_NOARGS,
7227
     PyDoc_STR("Return time object with same time and tzinfo.")},
7228
7229
    {"ctime", datetime_ctime, METH_NOARGS,
7230
     PyDoc_STR("Return ctime() style string.")},
7231
7232
    {"timetuple", datetime_timetuple, METH_NOARGS,
7233
     PyDoc_STR("Return time tuple, compatible with time.localtime().")},
7234
7235
    {"timestamp", datetime_timestamp, METH_NOARGS,
7236
     PyDoc_STR("Return POSIX timestamp as float.")},
7237
7238
    {"utctimetuple", datetime_utctimetuple, METH_NOARGS,
7239
     PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
7240
7241
    DATETIME_DATETIME_ISOFORMAT_METHODDEF
7242
7243
    {"utcoffset", datetime_utcoffset, METH_NOARGS,
7244
     PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
7245
7246
    {"tzname", datetime_tzname,   METH_NOARGS,
7247
     PyDoc_STR("Return self.tzinfo.tzname(self).")},
7248
7249
    {"dst", datetime_dst, METH_NOARGS,
7250
     PyDoc_STR("Return self.tzinfo.dst(self).")},
7251
7252
    DATETIME_DATETIME_REPLACE_METHODDEF
7253
7254
    {"__replace__", _PyCFunction_CAST(datetime_datetime_replace), METH_FASTCALL | METH_KEYWORDS,
7255
     PyDoc_STR("__replace__($self, /, **changes)\n--\n\nThe same as replace().")},
7256
7257
    DATETIME_DATETIME_ASTIMEZONE_METHODDEF
7258
    DATETIME_DATETIME___REDUCE_EX___METHODDEF
7259
    DATETIME_DATETIME___REDUCE___METHODDEF
7260
7261
    {NULL,      NULL}
7262
};
7263
7264
static PyNumberMethods datetime_as_number = {
7265
    datetime_add,                               /* nb_add */
7266
    datetime_subtract,                          /* nb_subtract */
7267
    0,                                          /* nb_multiply */
7268
    0,                                          /* nb_remainder */
7269
    0,                                          /* nb_divmod */
7270
    0,                                          /* nb_power */
7271
    0,                                          /* nb_negative */
7272
    0,                                          /* nb_positive */
7273
    0,                                          /* nb_absolute */
7274
    0,                                          /* nb_bool */
7275
};
7276
7277
static PyTypeObject PyDateTime_DateTimeType = {
7278
    PyVarObject_HEAD_INIT(NULL, 0)
7279
    "datetime.datetime",                        /* tp_name */
7280
    sizeof(PyDateTime_DateTime),                /* tp_basicsize */
7281
    0,                                          /* tp_itemsize */
7282
    datetime_dealloc,                           /* tp_dealloc */
7283
    0,                                          /* tp_vectorcall_offset */
7284
    0,                                          /* tp_getattr */
7285
    0,                                          /* tp_setattr */
7286
    0,                                          /* tp_as_async */
7287
    datetime_repr,                              /* tp_repr */
7288
    &datetime_as_number,                        /* tp_as_number */
7289
    0,                                          /* tp_as_sequence */
7290
    0,                                          /* tp_as_mapping */
7291
    datetime_hash,                              /* tp_hash */
7292
    0,                                          /* tp_call */
7293
    datetime_str,                               /* tp_str */
7294
    PyObject_GenericGetAttr,                    /* tp_getattro */
7295
    0,                                          /* tp_setattro */
7296
    0,                                          /* tp_as_buffer */
7297
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
7298
    datetime_datetime__doc__,                   /* tp_doc */
7299
    0,                                          /* tp_traverse */
7300
    0,                                          /* tp_clear */
7301
    datetime_richcompare,                       /* tp_richcompare */
7302
    0,                                          /* tp_weaklistoffset */
7303
    0,                                          /* tp_iter */
7304
    0,                                          /* tp_iternext */
7305
    datetime_methods,                           /* tp_methods */
7306
    0,                                          /* tp_members */
7307
    datetime_getset,                            /* tp_getset */
7308
    &PyDateTime_DateType,                       /* tp_base */
7309
    0,                                          /* tp_dict */
7310
    0,                                          /* tp_descr_get */
7311
    0,                                          /* tp_descr_set */
7312
    0,                                          /* tp_dictoffset */
7313
    0,                                          /* tp_init */
7314
    datetime_alloc,                             /* tp_alloc */
7315
    datetime_new,                               /* tp_new */
7316
    0,                                          /* tp_free */
7317
};
7318
7319
/* ---------------------------------------------------------------------------
7320
 * datetime C-API.
7321
 */
7322
7323
static PyTypeObject * const capi_types[] = {
7324
    &PyDateTime_DateType,
7325
    &PyDateTime_DateTimeType,
7326
    &PyDateTime_TimeType,
7327
    &PyDateTime_DeltaType,
7328
    &PyDateTime_TZInfoType,
7329
    /* Indirectly, via the utc object. */
7330
    &PyDateTime_TimeZoneType,
7331
};
7332
7333
/* The C-API is process-global.  This violates interpreter isolation
7334
 * due to the objects stored here.  Thus each of those objects must
7335
 * be managed carefully. */
7336
// XXX Can we make this const?
7337
static PyDateTime_CAPI capi = {
7338
    /* The classes must be readied before used here.
7339
     * That will happen the first time the module is loaded.
7340
     * They aren't safe to be shared between interpreters,
7341
     * but that's okay as long as the module is single-phase init. */
7342
    .DateType = &PyDateTime_DateType,
7343
    .DateTimeType = &PyDateTime_DateTimeType,
7344
    .TimeType = &PyDateTime_TimeType,
7345
    .DeltaType = &PyDateTime_DeltaType,
7346
    .TZInfoType = &PyDateTime_TZInfoType,
7347
7348
    .TimeZone_UTC = (PyObject *)&utc_timezone,
7349
7350
    .Date_FromDate = new_date_ex,
7351
    .DateTime_FromDateAndTime = new_datetime_ex,
7352
    .Time_FromTime = new_time_ex,
7353
    .Delta_FromDelta = new_delta_ex,
7354
    .TimeZone_FromTimeZone = new_timezone,
7355
    .DateTime_FromTimestamp = datetime_datetime_fromtimestamp_capi,
7356
    .Date_FromTimestamp = datetime_date_fromtimestamp_capi,
7357
    .DateTime_FromDateAndTimeAndFold = new_datetime_ex2,
7358
    .Time_FromTimeAndFold = new_time_ex2,
7359
};
7360
7361
/* Get a new C API by calling this function.
7362
 * Clients get at C API via PyDateTime_IMPORT, defined in datetime.h.
7363
 */
7364
static inline PyDateTime_CAPI *
7365
get_datetime_capi(void)
7366
14
{
7367
14
    return &capi;
7368
14
}
7369
7370
static PyObject *
7371
create_timezone_from_delta(int days, int sec, int ms, int normalize)
7372
72
{
7373
72
    PyObject *delta = new_delta(days, sec, ms, normalize);
7374
72
    if (delta == NULL) {
7375
0
        return NULL;
7376
0
    }
7377
72
    PyObject *tz = create_timezone(delta, NULL);
7378
72
    Py_DECREF(delta);
7379
72
    return tz;
7380
72
}
7381
7382
7383
/* ---------------------------------------------------------------------------
7384
 * Module state lifecycle.
7385
 */
7386
7387
static int
7388
init_state(datetime_state *st, PyObject *module, PyObject *old_module)
7389
14
{
7390
    /* Each module gets its own heap types. */
7391
14
#define ADD_TYPE(FIELD, SPEC, BASE)                 \
7392
14
    do {                                            \
7393
14
        PyObject *cls = PyType_FromModuleAndSpec(   \
7394
14
                module, SPEC, (PyObject *)BASE);    \
7395
14
        if (cls == NULL) {                          \
7396
0
            return -1;                              \
7397
0
        }                                           \
7398
14
        st->FIELD = (PyTypeObject *)cls;            \
7399
14
    } while (0)
7400
7401
14
    ADD_TYPE(isocalendar_date_type, &isocal_spec, &PyTuple_Type);
7402
14
#undef ADD_TYPE
7403
7404
14
    if (old_module != NULL) {
7405
0
        assert(old_module != module);
7406
0
        datetime_state *st_old = get_module_state(old_module);
7407
0
        *st = (datetime_state){
7408
0
            .isocalendar_date_type = st->isocalendar_date_type,
7409
0
            .us_per_ms = Py_NewRef(st_old->us_per_ms),
7410
0
            .us_per_second = Py_NewRef(st_old->us_per_second),
7411
0
            .us_per_minute = Py_NewRef(st_old->us_per_minute),
7412
0
            .us_per_hour = Py_NewRef(st_old->us_per_hour),
7413
0
            .us_per_day = Py_NewRef(st_old->us_per_day),
7414
0
            .us_per_week = Py_NewRef(st_old->us_per_week),
7415
0
            .seconds_per_day = Py_NewRef(st_old->seconds_per_day),
7416
0
            .epoch = Py_NewRef(st_old->epoch),
7417
0
        };
7418
0
        return 0;
7419
0
    }
7420
7421
14
    st->us_per_ms = PyLong_FromLong(1000);
7422
14
    if (st->us_per_ms == NULL) {
7423
0
        return -1;
7424
0
    }
7425
14
    st->us_per_second = PyLong_FromLong(1000000);
7426
14
    if (st->us_per_second == NULL) {
7427
0
        return -1;
7428
0
    }
7429
14
    st->us_per_minute = PyLong_FromLong(60000000);
7430
14
    if (st->us_per_minute == NULL) {
7431
0
        return -1;
7432
0
    }
7433
14
    st->seconds_per_day = PyLong_FromLong(24 * 3600);
7434
14
    if (st->seconds_per_day == NULL) {
7435
0
        return -1;
7436
0
    }
7437
7438
    /* The rest are too big for 32-bit ints, but even
7439
     * us_per_week fits in 40 bits, so doubles should be exact.
7440
     */
7441
14
    st->us_per_hour = PyLong_FromDouble(3600000000.0);
7442
14
    if (st->us_per_hour == NULL) {
7443
0
        return -1;
7444
0
    }
7445
14
    st->us_per_day = PyLong_FromDouble(86400000000.0);
7446
14
    if (st->us_per_day == NULL) {
7447
0
        return -1;
7448
0
    }
7449
14
    st->us_per_week = PyLong_FromDouble(604800000000.0);
7450
14
    if (st->us_per_week == NULL) {
7451
0
        return -1;
7452
0
    }
7453
7454
    /* Init Unix epoch */
7455
14
    st->epoch = new_datetime(
7456
14
            1970, 1, 1, 0, 0, 0, 0, (PyObject *)&utc_timezone, 0);
7457
14
    if (st->epoch == NULL) {
7458
0
        return -1;
7459
0
    }
7460
7461
14
    return 0;
7462
14
}
7463
7464
static int
7465
traverse_state(datetime_state *st, visitproc visit, void *arg)
7466
1.20k
{
7467
    /* heap types */
7468
1.20k
    Py_VISIT(st->isocalendar_date_type);
7469
7470
1.20k
    return 0;
7471
1.20k
}
7472
7473
static int
7474
clear_state(datetime_state *st)
7475
0
{
7476
0
    Py_CLEAR(st->isocalendar_date_type);
7477
0
    Py_CLEAR(st->us_per_ms);
7478
0
    Py_CLEAR(st->us_per_second);
7479
0
    Py_CLEAR(st->us_per_minute);
7480
0
    Py_CLEAR(st->us_per_hour);
7481
0
    Py_CLEAR(st->us_per_day);
7482
0
    Py_CLEAR(st->us_per_week);
7483
0
    Py_CLEAR(st->seconds_per_day);
7484
0
    Py_CLEAR(st->epoch);
7485
0
    return 0;
7486
0
}
7487
7488
7489
PyStatus
7490
_PyDateTime_InitTypes(PyInterpreterState *interp)
7491
36
{
7492
    /* Bases classes must be initialized before subclasses,
7493
     * so capi_types must have the types in the appropriate order. */
7494
252
    for (size_t i = 0; i < Py_ARRAY_LENGTH(capi_types); i++) {
7495
216
        PyTypeObject *type = capi_types[i];
7496
216
        if (_PyStaticType_InitForExtension(interp, type) < 0) {
7497
0
            return _PyStatus_ERR("could not initialize static types");
7498
0
        }
7499
216
    }
7500
7501
36
#define DATETIME_ADD_MACRO(dict, c, value_expr)         \
7502
504
    do {                                                \
7503
504
        assert(!PyErr_Occurred());                      \
7504
504
        PyObject *value = (value_expr);                 \
7505
504
        if (value == NULL) {                            \
7506
0
            goto error;                                 \
7507
0
        }                                               \
7508
504
        if (PyDict_SetItemString(dict, c, value) < 0) { \
7509
0
            Py_DECREF(value);                           \
7510
0
            goto error;                                 \
7511
0
        }                                               \
7512
504
        Py_DECREF(value);                               \
7513
504
    } while(0)
7514
7515
    /* timedelta values */
7516
36
    PyObject *d = _PyType_GetDict(&PyDateTime_DeltaType);
7517
36
    DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
7518
36
    DATETIME_ADD_MACRO(d, "min", new_delta(-MAX_DELTA_DAYS, 0, 0, 0));
7519
36
    DATETIME_ADD_MACRO(d, "max",
7520
36
                        new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0));
7521
7522
    /* date values */
7523
36
    d = _PyType_GetDict(&PyDateTime_DateType);
7524
36
    DATETIME_ADD_MACRO(d, "min", new_date(1, 1, 1));
7525
36
    DATETIME_ADD_MACRO(d, "max", new_date(MAXYEAR, 12, 31));
7526
36
    DATETIME_ADD_MACRO(d, "resolution", new_delta(1, 0, 0, 0));
7527
7528
    /* time values */
7529
36
    d = _PyType_GetDict(&PyDateTime_TimeType);
7530
36
    DATETIME_ADD_MACRO(d, "min", new_time(0, 0, 0, 0, Py_None, 0));
7531
36
    DATETIME_ADD_MACRO(d, "max", new_time(23, 59, 59, 999999, Py_None, 0));
7532
36
    DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
7533
7534
    /* datetime values */
7535
36
    d = _PyType_GetDict(&PyDateTime_DateTimeType);
7536
36
    DATETIME_ADD_MACRO(d, "min",
7537
36
                        new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0));
7538
36
    DATETIME_ADD_MACRO(d, "max", new_datetime(MAXYEAR, 12, 31, 23, 59, 59,
7539
36
                                                999999, Py_None, 0));
7540
36
    DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
7541
7542
    /* timezone values */
7543
36
    d = _PyType_GetDict(&PyDateTime_TimeZoneType);
7544
36
    if (PyDict_SetItemString(d, "utc", (PyObject *)&utc_timezone) < 0) {
7545
0
        goto error;
7546
0
    }
7547
7548
    /* bpo-37642: These attributes are rounded to the nearest minute for backwards
7549
    * compatibility, even though the constructor will accept a wider range of
7550
    * values. This may change in the future.*/
7551
7552
    /* -23:59 */
7553
36
    DATETIME_ADD_MACRO(d, "min", create_timezone_from_delta(-1, 60, 0, 1));
7554
7555
    /* +23:59 */
7556
36
    DATETIME_ADD_MACRO(
7557
36
            d, "max", create_timezone_from_delta(0, (23 * 60 + 59) * 60, 0, 0));
7558
7559
36
#undef DATETIME_ADD_MACRO
7560
7561
36
    return _PyStatus_OK();
7562
7563
0
error:
7564
0
    return _PyStatus_NO_MEMORY();
7565
36
}
7566
7567
7568
/* ---------------------------------------------------------------------------
7569
 * Module methods and initialization.
7570
 */
7571
7572
static PyMethodDef module_methods[] = {
7573
    {NULL, NULL}
7574
};
7575
7576
7577
static int
7578
_datetime_exec(PyObject *module)
7579
14
{
7580
14
    int rc = -1;
7581
14
    datetime_state *st = get_module_state(module);
7582
7583
14
    PyInterpreterState *interp = PyInterpreterState_Get();
7584
14
    PyObject *old_module = get_current_module(interp);
7585
14
    if (PyErr_Occurred()) {
7586
0
        assert(old_module == NULL);
7587
0
        goto error;
7588
0
    }
7589
    /* We actually set the "current" module right before a successful return. */
7590
7591
98
    for (size_t i = 0; i < Py_ARRAY_LENGTH(capi_types); i++) {
7592
84
        PyTypeObject *type = capi_types[i];
7593
84
        const char *name = _PyType_Name(type);
7594
84
        assert(name != NULL);
7595
84
        if (PyModule_AddObjectRef(module, name, (PyObject *)type) < 0) {
7596
0
            goto error;
7597
0
        }
7598
84
    }
7599
7600
14
    if (init_state(st, module, old_module) < 0) {
7601
0
        goto error;
7602
0
    }
7603
7604
    /* Add module level attributes */
7605
14
    if (PyModule_AddIntMacro(module, MINYEAR) < 0) {
7606
0
        goto error;
7607
0
    }
7608
14
    if (PyModule_AddIntMacro(module, MAXYEAR) < 0) {
7609
0
        goto error;
7610
0
    }
7611
14
    if (PyModule_AddObjectRef(module, "UTC", (PyObject *)&utc_timezone) < 0) {
7612
0
        goto error;
7613
0
    }
7614
7615
    /* At last, set up and add the encapsulated C API */
7616
14
    PyDateTime_CAPI *capi = get_datetime_capi();
7617
14
    if (capi == NULL) {
7618
0
        goto error;
7619
0
    }
7620
14
    PyObject *capsule = PyCapsule_New(capi, PyDateTime_CAPSULE_NAME, NULL);
7621
    // (capsule == NULL) is handled by PyModule_Add
7622
14
    if (PyModule_Add(module, "datetime_CAPI", capsule) < 0) {
7623
0
        goto error;
7624
0
    }
7625
7626
    /* A 4-year cycle has an extra leap day over what we'd get from
7627
     * pasting together 4 single years.
7628
     */
7629
14
    static_assert(DI4Y == 4 * 365 + 1, "DI4Y");
7630
14
    assert(DI4Y == days_before_year(4+1));
7631
7632
    /* Similarly, a 400-year cycle has an extra leap day over what we'd
7633
     * get from pasting together 4 100-year cycles.
7634
     */
7635
14
    static_assert(DI400Y == 4 * DI100Y + 1, "DI400Y");
7636
14
    assert(DI400Y == days_before_year(400+1));
7637
7638
    /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
7639
     * pasting together 25 4-year cycles.
7640
     */
7641
14
    static_assert(DI100Y == 25 * DI4Y - 1, "DI100Y");
7642
14
    assert(DI100Y == days_before_year(100+1));
7643
7644
14
    if (set_current_module(interp, module) < 0) {
7645
0
        goto error;
7646
0
    }
7647
7648
14
    rc = 0;
7649
14
    goto finally;
7650
7651
0
error:
7652
0
    clear_state(st);
7653
7654
14
finally:
7655
14
    Py_XDECREF(old_module);
7656
14
    return rc;
7657
0
}
7658
7659
static PyModuleDef_Slot module_slots[] = {
7660
    _Py_ABI_SLOT,
7661
    {Py_mod_exec, _datetime_exec},
7662
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
7663
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
7664
    {0, NULL},
7665
};
7666
7667
static int
7668
module_traverse(PyObject *mod, visitproc visit, void *arg)
7669
1.20k
{
7670
1.20k
    datetime_state *st = get_module_state(mod);
7671
1.20k
    traverse_state(st, visit, arg);
7672
1.20k
    return 0;
7673
1.20k
}
7674
7675
static int
7676
module_clear(PyObject *mod)
7677
0
{
7678
0
    datetime_state *st = get_module_state(mod);
7679
0
    clear_state(st);
7680
7681
0
    PyInterpreterState *interp = PyInterpreterState_Get();
7682
0
    clear_current_module(interp, mod);
7683
7684
    // The runtime takes care of the static types for us.
7685
    // See _PyTypes_FiniExtTypes()..
7686
7687
0
    return 0;
7688
0
}
7689
7690
static void
7691
module_free(void *mod)
7692
0
{
7693
0
    (void)module_clear((PyObject *)mod);
7694
0
}
7695
7696
static PyModuleDef datetimemodule = {
7697
    .m_base = PyModuleDef_HEAD_INIT,
7698
    .m_name = "_datetime",
7699
    .m_doc = "Fast implementation of the datetime module.",
7700
    .m_size = sizeof(datetime_state),
7701
    .m_methods = module_methods,
7702
    .m_slots = module_slots,
7703
    .m_traverse = module_traverse,
7704
    .m_clear = module_clear,
7705
    .m_free = module_free,
7706
};
7707
7708
PyMODINIT_FUNC
7709
PyInit__datetime(void)
7710
14
{
7711
14
    return PyModuleDef_Init(&datetimemodule);
7712
14
}
7713
7714
/* ---------------------------------------------------------------------------
7715
Some time zone algebra.  For a datetime x, let
7716
    x.n = x stripped of its timezone -- its naive time.
7717
    x.o = x.utcoffset(), and assuming that doesn't raise an exception or
7718
      return None
7719
    x.d = x.dst(), and assuming that doesn't raise an exception or
7720
      return None
7721
    x.s = x's standard offset, x.o - x.d
7722
7723
Now some derived rules, where k is a duration (timedelta).
7724
7725
1. x.o = x.s + x.d
7726
   This follows from the definition of x.s.
7727
7728
2. If x and y have the same tzinfo member, x.s = y.s.
7729
   This is actually a requirement, an assumption we need to make about
7730
   sane tzinfo classes.
7731
7732
3. The naive UTC time corresponding to x is x.n - x.o.
7733
   This is again a requirement for a sane tzinfo class.
7734
7735
4. (x+k).s = x.s
7736
   This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
7737
7738
5. (x+k).n = x.n + k
7739
   Again follows from how arithmetic is defined.
7740
7741
Now we can explain tz.fromutc(x).  Let's assume it's an interesting case
7742
(meaning that the various tzinfo methods exist, and don't blow up or return
7743
None when called).
7744
7745
The function wants to return a datetime y with timezone tz, equivalent to x.
7746
x is already in UTC.
7747
7748
By #3, we want
7749
7750
    y.n - y.o = x.n                             [1]
7751
7752
The algorithm starts by attaching tz to x.n, and calling that y.  So
7753
x.n = y.n at the start.  Then it wants to add a duration k to y, so that [1]
7754
becomes true; in effect, we want to solve [2] for k:
7755
7756
   (y+k).n - (y+k).o = x.n                      [2]
7757
7758
By #1, this is the same as
7759
7760
   (y+k).n - ((y+k).s + (y+k).d) = x.n          [3]
7761
7762
By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
7763
Substituting that into [3],
7764
7765
   x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
7766
   k - (y+k).s - (y+k).d = 0; rearranging,
7767
   k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
7768
   k = y.s - (y+k).d
7769
7770
On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
7771
approximate k by ignoring the (y+k).d term at first.  Note that k can't be
7772
very large, since all offset-returning methods return a duration of magnitude
7773
less than 24 hours.  For that reason, if y is firmly in std time, (y+k).d must
7774
be 0, so ignoring it has no consequence then.
7775
7776
In any case, the new value is
7777
7778
    z = y + y.s                                 [4]
7779
7780
It's helpful to step back at look at [4] from a higher level:  it's simply
7781
mapping from UTC to tz's standard time.
7782
7783
At this point, if
7784
7785
    z.n - z.o = x.n                             [5]
7786
7787
we have an equivalent time, and are almost done.  The insecurity here is
7788
at the start of daylight time.  Picture US Eastern for concreteness.  The wall
7789
time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
7790
sense then.  The docs ask that an Eastern tzinfo class consider such a time to
7791
be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
7792
on the day DST starts.  We want to return the 1:MM EST spelling because that's
7793
the only spelling that makes sense on the local wall clock.
7794
7795
In fact, if [5] holds at this point, we do have the standard-time spelling,
7796
but that takes a bit of proof.  We first prove a stronger result.  What's the
7797
difference between the LHS and RHS of [5]?  Let
7798
7799
    diff = x.n - (z.n - z.o)                    [6]
7800
7801
Now
7802
    z.n =                       by [4]
7803
    (y + y.s).n =               by #5
7804
    y.n + y.s =                 since y.n = x.n
7805
    x.n + y.s =                 since z and y are have the same tzinfo member,
7806
                                    y.s = z.s by #2
7807
    x.n + z.s
7808
7809
Plugging that back into [6] gives
7810
7811
    diff =
7812
    x.n - ((x.n + z.s) - z.o) =     expanding
7813
    x.n - x.n - z.s + z.o =         cancelling
7814
    - z.s + z.o =                   by #2
7815
    z.d
7816
7817
So diff = z.d.
7818
7819
If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
7820
spelling we wanted in the endcase described above.  We're done.  Contrarily,
7821
if z.d = 0, then we have a UTC equivalent, and are also done.
7822
7823
If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
7824
add to z (in effect, z is in tz's standard time, and we need to shift the
7825
local clock into tz's daylight time).
7826
7827
Let
7828
7829
    z' = z + z.d = z + diff                     [7]
7830
7831
and we can again ask whether
7832
7833
    z'.n - z'.o = x.n                           [8]
7834
7835
If so, we're done.  If not, the tzinfo class is insane, according to the
7836
assumptions we've made.  This also requires a bit of proof.  As before, let's
7837
compute the difference between the LHS and RHS of [8] (and skipping some of
7838
the justifications for the kinds of substitutions we've done several times
7839
already):
7840
7841
    diff' = x.n - (z'.n - z'.o) =           replacing z'.n via [7]
7842
        x.n  - (z.n + diff - z'.o) =    replacing diff via [6]
7843
        x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
7844
        x.n - z.n - x.n + z.n - z.o + z'.o =    cancel x.n
7845
        - z.n + z.n - z.o + z'.o =              cancel z.n
7846
        - z.o + z'.o =                      #1 twice
7847
        -z.s - z.d + z'.s + z'.d =          z and z' have same tzinfo
7848
        z'.d - z.d
7849
7850
So z' is UTC-equivalent to x iff z'.d = z.d at this point.  If they are equal,
7851
we've found the UTC-equivalent so are done.  In fact, we stop with [7] and
7852
return z', not bothering to compute z'.d.
7853
7854
How could z.d and z'd differ?  z' = z + z.d [7], so merely moving z' by
7855
a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
7856
would have to change the result dst() returns:  we start in DST, and moving
7857
a little further into it takes us out of DST.
7858
7859
There isn't a sane case where this can happen.  The closest it gets is at
7860
the end of DST, where there's an hour in UTC with no spelling in a hybrid
7861
tzinfo class.  In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT.  During
7862
that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
7863
UTC) because the docs insist on that, but 0:MM is taken as being in daylight
7864
time (4:MM UTC).  There is no local time mapping to 5:MM UTC.  The local
7865
clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
7866
standard time.  Since that's what the local clock *does*, we want to map both
7867
UTC hours 5:MM and 6:MM to 1:MM Eastern.  The result is ambiguous
7868
in local time, but so it goes -- it's the way the local clock works.
7869
7870
When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
7871
so z=0:MM.  z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
7872
z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
7873
(correctly) concludes that z' is not UTC-equivalent to x.
7874
7875
Because we know z.d said z was in daylight time (else [5] would have held and
7876
we would have stopped then), and we know z.d != z'.d (else [8] would have held
7877
and we would have stopped then), and there are only 2 possible values dst() can
7878
return in Eastern, it follows that z'.d must be 0 (which it is in the example,
7879
but the reasoning doesn't depend on the example -- it depends on there being
7880
two possible dst() outcomes, one zero and the other non-zero).  Therefore
7881
z' must be in standard time, and is the spelling we want in this case.
7882
7883
Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
7884
concerned (because it takes z' as being in standard time rather than the
7885
daylight time we intend here), but returning it gives the real-life "local
7886
clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
7887
tz.
7888
7889
When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
7890
the 1:MM standard time spelling we want.
7891
7892
So how can this break?  One of the assumptions must be violated.  Two
7893
possibilities:
7894
7895
1) [2] effectively says that y.s is invariant across all y belong to a given
7896
   time zone.  This isn't true if, for political reasons or continental drift,
7897
   a region decides to change its base offset from UTC.
7898
7899
2) There may be versions of "double daylight" time where the tail end of
7900
   the analysis gives up a step too early.  I haven't thought about that
7901
   enough to say.
7902
7903
In any case, it's clear that the default fromutc() is strong enough to handle
7904
"almost all" time zones:  so long as the standard offset is invariant, it
7905
doesn't matter if daylight time transition points change from year to year, or
7906
if daylight time is skipped in some years; it doesn't matter how large or
7907
small dst() may get within its bounds; and it doesn't even matter if some
7908
perverse time zone returns a negative dst()).  So a breaking case must be
7909
pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
7910
--------------------------------------------------------------------------- */