Coverage Report

Created: 2026-03-08 06:40

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