Coverage Report

Created: 2026-09-27 06:15

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