Coverage Report

Created: 2026-07-14 06:16

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