Coverage Report

Created: 2025-10-10 06:33

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