Coverage Report

Created: 2026-10-31 06:21

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