Coverage Report

Created: 2026-06-21 06:15

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