Coverage Report

Created: 2026-02-26 06:53

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
22
#define DATETIME_TYPE(st) &PyDateTime_DateTimeType
76
0
#define TIME_TYPE(st) &PyDateTime_TimeType
77
86
#define DELTA_TYPE(st) &PyDateTime_DeltaType
78
#define TZINFO_TYPE(st) &PyDateTime_TZInfoType
79
64
#define TIMEZONE_TYPE(st) &PyDateTime_TimeZoneType
80
0
#define ISOCALENDAR_DATE_TYPE(st) st->isocalendar_date_type
81
82
15
#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
76
#define PyDateTime_CAST(op) ((PyDateTime_DateTime *)(op))
87
17
#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
135
#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
179
#define PyDelta_CAST(op) ((PyDateTime_Delta *)(op))
95
23
#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
12
#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
2
#define CONST_US_PER_MS(st) st->us_per_ms
108
140
#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
4
#define CONST_US_PER_DAY(st) st->us_per_day
112
0
#define CONST_US_PER_WEEK(st) st->us_per_week
113
89
#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
955
{
120
955
    void *state = _PyModule_GetState(module);
121
955
    assert(state != NULL);
122
955
    return (datetime_state *)state;
123
955
}
124
125
126
170
#define INTERP_KEY ((PyObject *)&_Py_ID(cached_datetime_module))
127
128
static PyObject *
129
get_current_module(PyInterpreterState *interp)
130
158
{
131
158
    PyObject *mod = NULL;
132
133
158
    PyObject *dict = PyInterpreterState_GetDict(interp);
134
158
    if (dict == NULL) {
135
0
        goto error;
136
0
    }
137
158
    PyObject *ref = NULL;
138
158
    if (PyDict_GetItemRef(dict, INTERP_KEY, &ref) < 0) {
139
0
        goto error;
140
0
    }
141
158
    if (ref != NULL) {
142
146
        if (ref != Py_None) {
143
146
            (void)PyWeakref_GetRef(ref, &mod);
144
146
            if (mod == Py_None) {
145
0
                Py_CLEAR(mod);
146
0
            }
147
146
            Py_DECREF(ref);
148
146
        }
149
146
    }
150
158
    return mod;
151
152
0
error:
153
0
    assert(PyErr_Occurred());
154
0
    return NULL;
155
158
}
156
157
static PyModuleDef datetimemodule;
158
159
static datetime_state *
160
_get_current_state(PyObject **p_mod)
161
146
{
162
146
    PyInterpreterState *interp = PyInterpreterState_Get();
163
146
    PyObject *mod = get_current_module(interp);
164
146
    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
146
    datetime_state *st = get_module_state(mod);
177
146
    *p_mod = mod;
178
146
    return st;
179
146
}
180
181
#define GET_CURRENT_STATE(MOD_VAR)  \
182
146
    _get_current_state(&MOD_VAR)
183
#define RELEASE_CURRENT_STATE(ST_VAR, MOD_VAR)  \
184
146
    Py_DECREF(MOD_VAR)
185
186
static int
187
set_current_module(PyInterpreterState *interp, PyObject *mod)
188
12
{
189
12
    assert(mod != NULL);
190
12
    PyObject *dict = PyInterpreterState_GetDict(interp);
191
12
    if (dict == NULL) {
192
0
        return -1;
193
0
    }
194
12
    PyObject *ref = PyWeakref_NewRef(mod, NULL);
195
12
    if (ref == NULL) {
196
0
        return -1;
197
0
    }
198
12
    int rc = PyDict_SetItem(dict, INTERP_KEY, ref);
199
12
    Py_DECREF(ref);
200
12
    return rc;
201
12
}
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
657
#define MINYEAR 1
258
331
#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
614
#define MAX_DELTA_DAYS 999999999
267
268
/* Rename the long macros in datetime.h to more reasonable short names. */
269
120
#define GET_YEAR                PyDateTime_GET_YEAR
270
120
#define GET_MONTH               PyDateTime_GET_MONTH
271
120
#define GET_DAY                 PyDateTime_GET_DAY
272
22
#define DATE_GET_HOUR           PyDateTime_DATE_GET_HOUR
273
22
#define DATE_GET_MINUTE         PyDateTime_DATE_GET_MINUTE
274
22
#define DATE_GET_SECOND         PyDateTime_DATE_GET_SECOND
275
17
#define DATE_GET_MICROSECOND    PyDateTime_DATE_GET_MICROSECOND
276
5
#define DATE_GET_FOLD           PyDateTime_DATE_GET_FOLD
277
278
/* Date accessors for date and datetime. */
279
323
#define SET_YEAR(o, v)          (((o)->data[0] = ((v) & 0xff00) >> 8), \
280
323
                 ((o)->data[1] = ((v) & 0x00ff)))
281
323
#define SET_MONTH(o, v)         (PyDateTime_GET_MONTH(o) = (v))
282
323
#define SET_DAY(o, v)           (PyDateTime_GET_DAY(o) = (v))
283
284
/* Date/Time accessors for datetime. */
285
131
#define DATE_SET_HOUR(o, v)     (PyDateTime_DATE_GET_HOUR(o) = (v))
286
131
#define DATE_SET_MINUTE(o, v)   (PyDateTime_DATE_GET_MINUTE(o) = (v))
287
131
#define DATE_SET_SECOND(o, v)   (PyDateTime_DATE_GET_SECOND(o) = (v))
288
#define DATE_SET_MICROSECOND(o, v)      \
289
131
    (((o)->data[7] = ((v) & 0xff0000) >> 16), \
290
131
     ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
291
131
     ((o)->data[9] = ((v) & 0x0000ff)))
292
131
#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
199
#define TIME_SET_HOUR(o, v)     (PyDateTime_TIME_GET_HOUR(o) = (v))
301
199
#define TIME_SET_MINUTE(o, v)   (PyDateTime_TIME_GET_MINUTE(o) = (v))
302
199
#define TIME_SET_SECOND(o, v)   (PyDateTime_TIME_GET_SECOND(o) = (v))
303
#define TIME_SET_MICROSECOND(o, v)      \
304
199
    (((o)->data[3] = ((v) & 0xff0000) >> 16), \
305
199
     ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
306
199
     ((o)->data[5] = ((v) & 0x0000ff)))
307
199
#define TIME_SET_FOLD(o, v)   (PyDateTime_TIME_GET_FOLD(o) = (v))
308
309
/* Delta accessors for timedelta. */
310
51
#define GET_TD_DAYS(o)          (PyDelta_CAST(o)->days)
311
51
#define GET_TD_SECONDS(o)       (PyDelta_CAST(o)->seconds)
312
51
#define GET_TD_MICROSECONDS(o)  (PyDelta_CAST(o)->microseconds)
313
314
295
#define SET_TD_DAYS(o, v)       ((o)->days = (v))
315
295
#define SET_TD_SECONDS(o, v)    ((o)->seconds = (v))
316
295
#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
317
318
176
#define HASTZINFO               _PyDateTime_HAS_TZINFO
319
0
#define GET_TIME_TZINFO         PyDateTime_TIME_GET_TZINFO
320
17
#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
221
{
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
221
    const unsigned int ayear = (unsigned int)year;
425
221
    return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
426
221
}
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
331
{
432
331
    assert(month >= 1);
433
331
    assert(month <= 12);
434
331
    if (month == 2 && is_leap(year))
435
12
        return 29;
436
319
    else
437
319
        return _days_in_month[month];
438
331
}
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
206
{
444
206
    int days;
445
446
206
    assert(month >= 1);
447
206
    assert(month <= 12);
448
206
    days = _days_before_month[month];
449
206
    if (month > 2 && is_leap(year))
450
0
        ++days;
451
206
    return days;
452
206
}
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
110
{
460
110
    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
110
    assert (year >= 1);
466
110
    return y*365 + y/4 - y/100 + y/400;
467
110
}
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
110
{
564
110
    return days_before_year(year) + days_before_month(year, month) + day;
565
110
}
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
96
{
571
96
    return (ymd_to_ord(year, month, day) + 6) % 7;
572
96
}
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
307
{
638
307
    if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
639
307
        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
307
}
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
326
{
652
653
326
    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
326
    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
326
    int dim = days_in_month(year, month);
664
326
    if (day < 1 || day > dim) {
665
3
        PyErr_Format(PyExc_ValueError,
666
3
                     "day %i must be in range 1..%d for month %i in year %i",
667
3
                     day, dim, month, year);
668
3
        return -1;
669
3
    }
670
323
    return 0;
671
326
}
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
330
{
679
330
    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
330
    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
330
    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
330
    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
330
    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
330
    return 0;
702
330
}
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
20
{
717
20
    assert(factor > 0);
718
20
    assert(lo != hi);
719
20
    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
20
    assert(0 <= *lo && *lo < factor);
726
20
}
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
38
{
737
38
    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
38
    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
38
    assert(0 <= *s && *s < 24*3600);
752
38
    assert(0 <= *us && *us < 1000000);
753
38
}
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
5
{
764
5
    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
5
    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
5
    dim = days_in_month(*y, *m);
778
5
    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
5
    assert(*m > 0);
814
5
    assert(*d > 0);
815
5
    if (MINYEAR <= *y && *y <= MAXYEAR)
816
5
        return 0;
817
0
 error:
818
0
    PyErr_SetString(PyExc_OverflowError,
819
0
            "date value out of range");
820
0
    return -1;
821
822
5
}
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
5
{
831
5
    return normalize_y_m_d(year, month, day);
832
5
}
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
5
{
842
5
    normalize_pair(second, microsecond, 1000000);
843
5
    normalize_pair(minute, second, 60);
844
5
    normalize_pair(hour, minute, 60);
845
5
    normalize_pair(day, hour, 24);
846
5
    return normalize_date(year, month, day);
847
5
}
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
199
{
873
199
    size_t size = aware ? sizeof(PyDateTime_Time) : sizeof(_PyDateTime_BaseTime);
874
199
    PyObject *self = (PyObject *)PyObject_Malloc(size);
875
199
    if (self == NULL) {
876
0
        return PyErr_NoMemory();
877
0
    }
878
199
    _PyObject_Init(self, type);
879
199
    return self;
880
199
}
881
882
static PyObject *
883
datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
884
131
{
885
131
    size_t size = aware ? sizeof(PyDateTime_DateTime) : sizeof(_PyDateTime_BaseDateTime);
886
131
    PyObject *self = (PyObject *)PyObject_Malloc(size);
887
131
    if (self == NULL) {
888
0
        return PyErr_NoMemory();
889
0
    }
890
131
    _PyObject_Init(self, type);
891
131
    return self;
892
131
}
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
323
{
903
323
    self->hashcode = -1;
904
323
    SET_YEAR(self, y);
905
323
    SET_MONTH(self, m);
906
323
    SET_DAY(self, d);
907
323
}
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
195
{
1156
195
    PyDateTime_Date *self;
1157
1158
195
    if (check_date_args(year, month, day) < 0) {
1159
3
        return NULL;
1160
3
    }
1161
1162
192
    self = (PyDateTime_Date *)(type->tp_alloc(type, 0));
1163
192
    if (self != NULL)
1164
192
        set_date_fields(self, year, month, day);
1165
192
    return (PyObject *)self;
1166
195
}
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
131
{
1199
131
    PyDateTime_DateTime *self;
1200
131
    char aware = tzinfo != Py_None;
1201
1202
131
    if (check_date_args(year, month, day) < 0) {
1203
0
        return NULL;
1204
0
    }
1205
131
    if (check_time_args(hour, minute, second, usecond, fold) < 0) {
1206
0
        return NULL;
1207
0
    }
1208
131
    if (check_tzinfo_subclass(tzinfo) < 0) {
1209
0
        return NULL;
1210
0
    }
1211
1212
131
    self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
1213
131
    if (self != NULL) {
1214
131
        self->hastzinfo = aware;
1215
131
        set_date_fields((PyDateTime_Date *)self, year, month, day);
1216
131
        DATE_SET_HOUR(self, hour);
1217
131
        DATE_SET_MINUTE(self, minute);
1218
131
        DATE_SET_SECOND(self, second);
1219
131
        DATE_SET_MICROSECOND(self, usecond);
1220
131
        if (aware) {
1221
12
            self->tzinfo = Py_NewRef(tzinfo);
1222
12
        }
1223
131
        DATE_SET_FOLD(self, fold);
1224
131
    }
1225
131
    return (PyObject *)self;
1226
131
}
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
17
    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
5
{
1278
5
    PyObject* dt;
1279
5
    if (cls == DATETIME_TYPE(NO_STATE)) {
1280
        // Use the fast path constructor
1281
5
        dt = new_datetime(year, month, day, hour, minute, second, usecond,
1282
5
                          tzinfo, fold);
1283
5
    }
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
5
    return dt;
1291
5
}
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
5
                              PyTypeObject *cls) {
1297
5
    return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
1298
5
                                         second, usecond, tzinfo, 0,
1299
5
                                         cls);
1300
5
}
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
199
{
1307
199
    PyDateTime_Time *self;
1308
199
    char aware = tzinfo != Py_None;
1309
1310
199
    if (check_time_args(hour, minute, second, usecond, fold) < 0) {
1311
0
        return NULL;
1312
0
    }
1313
199
    if (check_tzinfo_subclass(tzinfo) < 0) {
1314
0
        return NULL;
1315
0
    }
1316
1317
199
    self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
1318
199
    if (self != NULL) {
1319
199
        self->hastzinfo = aware;
1320
199
        self->hashcode = -1;
1321
199
        TIME_SET_HOUR(self, hour);
1322
199
        TIME_SET_MINUTE(self, minute);
1323
199
        TIME_SET_SECOND(self, second);
1324
199
        TIME_SET_MICROSECOND(self, usecond);
1325
199
        if (aware) {
1326
0
            self->tzinfo = Py_NewRef(tzinfo);
1327
0
        }
1328
199
        TIME_SET_FOLD(self, fold);
1329
199
    }
1330
199
    return (PyObject *)self;
1331
199
}
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
307
{
1373
307
    PyDateTime_Delta *self;
1374
1375
307
    if (normalize)
1376
38
        normalize_d_s_us(&days, &seconds, &microseconds);
1377
307
    assert(0 <= seconds && seconds < 24*3600);
1378
307
    assert(0 <= microseconds && microseconds < 1000000);
1379
1380
307
    if (check_delta_day_range(days) < 0)
1381
0
        return NULL;
1382
1383
307
    self = look_up_delta(days, seconds, microseconds, type);
1384
307
    if (self != NULL) {
1385
12
        return (PyObject *)self;
1386
12
    }
1387
307
    assert(!PyErr_Occurred());
1388
1389
295
    self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
1390
295
    if (self != NULL) {
1391
295
        self->hashcode = -1;
1392
295
        SET_TD_DAYS(self, days);
1393
295
        SET_TD_SECONDS(self, seconds);
1394
295
        SET_TD_MICROSECONDS(self, microseconds);
1395
295
    }
1396
295
    return (PyObject *) self;
1397
307
}
1398
1399
#define new_delta(d, s, us, normalize)  \
1400
70
    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
64
{
1419
64
    PyDateTime_TimeZone *self;
1420
64
    PyTypeObject *type = TIMEZONE_TYPE(NO_STATE);
1421
1422
64
    assert(offset != NULL);
1423
64
    assert(PyDelta_Check(offset));
1424
64
    assert(name == NULL || PyUnicode_Check(name));
1425
1426
64
    self = look_up_timezone(offset, name);
1427
64
    if (self != NULL) {
1428
0
        return (PyObject *)self;
1429
0
    }
1430
64
    assert(!PyErr_Occurred());
1431
1432
64
    self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
1433
64
    if (self == NULL) {
1434
0
        return NULL;
1435
0
    }
1436
64
    self->offset = Py_NewRef(offset);
1437
64
    self->name = Py_XNewRef(name);
1438
64
    return (PyObject *)self;
1439
64
}
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
330
{
1477
330
    if (p == Py_None || PyTZInfo_Check(p))
1478
330
        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
330
}
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
5
{
1513
5
    PyObject *offset;
1514
1515
5
    assert(tzinfo != NULL);
1516
5
    assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
1517
5
    assert(tzinfoarg != NULL);
1518
1519
5
    if (tzinfo == Py_None)
1520
5
        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
5
{
1559
5
    return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
1560
5
}
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
96
{
1768
96
    static int cache = -1;
1769
96
    if (cache < 0) {
1770
2
        char year[5];
1771
2
        struct tm date = {
1772
2
            .tm_year = -1801,
1773
2
            .tm_mon = 0,
1774
2
            .tm_mday = 1
1775
2
        };
1776
2
        cache = (strftime(year, sizeof(year), "%Y", &date) &&
1777
2
                 strcmp(year, "0099") != 0);
1778
2
    }
1779
96
    return cache;
1780
96
}
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
96
{
1871
96
    PyObject *result = NULL;            /* guilty until proved innocent */
1872
1873
96
    PyObject *zreplacement = NULL;      /* py string, replacement for %z */
1874
96
    PyObject *colonzreplacement = NULL; /* py string, replacement for %:z */
1875
96
    PyObject *Zreplacement = NULL;      /* py string, replacement for %Z */
1876
96
    PyObject *freplacement = NULL;      /* py string, replacement for %f */
1877
1878
96
    assert(object && format && timetuple);
1879
96
    assert(PyUnicode_Check(format));
1880
1881
96
    PyObject *strftime = PyImport_ImportModuleAttrString("time", "strftime");
1882
96
    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
96
    PyUnicodeWriter *writer = PyUnicodeWriter_Create(0);
1892
96
    if (writer == NULL) {
1893
0
        goto Error;
1894
0
    }
1895
1896
96
    Py_ssize_t flen = PyUnicode_GET_LENGTH(format);
1897
96
    Py_ssize_t i = 0;
1898
96
    Py_ssize_t start = 0;
1899
96
    Py_ssize_t end = 0;
1900
192
    while (i != flen) {
1901
144
        i = PyUnicode_FindChar(format, '%', i, flen, 1);
1902
144
        if (i < 0) {
1903
48
            assert(!PyErr_Occurred());
1904
48
            break;
1905
48
        }
1906
96
        end = i;
1907
96
        i++;
1908
96
        if (i == flen) {
1909
0
            break;
1910
0
        }
1911
96
        Py_UCS4 ch = PyUnicode_READ_CHAR(format, i);
1912
96
        i++;
1913
        /* A % has been seen and ch is the character after it. */
1914
96
        PyObject *replacement = NULL;
1915
96
        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
96
        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
96
        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
96
        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
96
        else if (normalize_century()
1954
96
                 && (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
96
        else {
2007
            /* percent followed by something else */
2008
96
            continue;
2009
96
        }
2010
96
        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
96
    PyObject *newformat;
2022
96
    if (start == 0) {
2023
96
        PyUnicodeWriter_Discard(writer);
2024
96
        newformat = Py_NewRef(format);
2025
96
    }
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
96
    result = PyObject_CallFunctionObjArgs(strftime,
2036
96
                                          newformat, timetuple, NULL);
2037
96
    Py_DECREF(newformat);
2038
2039
96
 Done:
2040
96
    Py_XDECREF(freplacement);
2041
96
    Py_XDECREF(zreplacement);
2042
96
    Py_XDECREF(colonzreplacement);
2043
96
    Py_XDECREF(Zreplacement);
2044
96
    Py_XDECREF(strftime);
2045
96
    return result;
2046
2047
0
 Error:
2048
0
    PyUnicodeWriter_Discard(writer);
2049
0
    goto Done;
2050
96
}
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
96
{
2077
96
    PyObject *struct_time;
2078
96
    PyObject *result;
2079
2080
96
    struct_time = PyImport_ImportModuleAttrString("time", "struct_time");
2081
96
    if (struct_time == NULL) {
2082
0
        return NULL;
2083
0
    }
2084
2085
96
    result = PyObject_CallFunction(struct_time, "((iiiiiiiii))",
2086
96
                         y, m, d,
2087
96
                         hh, mm, ss,
2088
96
                         weekday(y, m, d),
2089
96
                         days_before_month(y, m) + d,
2090
96
                         dstflag);
2091
96
    Py_DECREF(struct_time);
2092
96
    return result;
2093
96
}
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
2
{
2105
2
    Py_RETURN_RICHCOMPARE(diff, 0, op);
2106
2
}
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
42
{
2125
42
    PyObject *x1 = NULL;
2126
42
    PyObject *x2 = NULL;
2127
42
    PyObject *x3 = NULL;
2128
42
    PyObject *result = NULL;
2129
2130
42
    PyObject *current_mod = NULL;
2131
42
    datetime_state *st = GET_CURRENT_STATE(current_mod);
2132
2133
42
    x1 = PyLong_FromLong(GET_TD_DAYS(self));
2134
42
    if (x1 == NULL)
2135
0
        goto Done;
2136
42
    x2 = PyNumber_Multiply(x1, CONST_SEC_PER_DAY(st));        /* days in seconds */
2137
42
    if (x2 == NULL)
2138
0
        goto Done;
2139
42
    Py_SETREF(x1, NULL);
2140
2141
    /* x2 has days in seconds */
2142
42
    x1 = PyLong_FromLong(GET_TD_SECONDS(self));         /* seconds */
2143
42
    if (x1 == NULL)
2144
0
        goto Done;
2145
42
    x3 = PyNumber_Add(x1, x2);          /* days and seconds in seconds */
2146
42
    if (x3 == NULL)
2147
0
        goto Done;
2148
42
    Py_DECREF(x1);
2149
42
    Py_DECREF(x2);
2150
42
    /* x1 = */ x2 = NULL;
2151
2152
    /* x3 has days+seconds in seconds */
2153
42
    x1 = PyNumber_Multiply(x3, CONST_US_PER_SECOND(st));          /* us */
2154
42
    if (x1 == NULL)
2155
0
        goto Done;
2156
42
    Py_SETREF(x3, NULL);
2157
2158
    /* x1 has days+seconds in us */
2159
42
    x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
2160
42
    if (x2 == NULL)
2161
0
        goto Done;
2162
42
    result = PyNumber_Add(x1, x2);
2163
42
    assert(result == NULL || PyLong_CheckExact(result));
2164
2165
42
Done:
2166
42
    Py_XDECREF(x1);
2167
42
    Py_XDECREF(x2);
2168
42
    Py_XDECREF(x3);
2169
42
    RELEASE_CURRENT_STATE(st, current_mod);
2170
42
    return result;
2171
42
}
2172
2173
static PyObject *
2174
checked_divmod(PyObject *a, PyObject *b)
2175
94
{
2176
94
    PyObject *result = PyNumber_Divmod(a, b);
2177
94
    if (result != NULL) {
2178
94
        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
94
        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
94
    }
2193
94
    return result;
2194
94
}
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
47
{
2201
47
    int us;
2202
47
    int s;
2203
47
    int d;
2204
2205
47
    PyObject *tuple = NULL;
2206
47
    PyObject *num = NULL;
2207
47
    PyObject *result = NULL;
2208
2209
47
    PyObject *current_mod = NULL;
2210
47
    datetime_state *st = GET_CURRENT_STATE(current_mod);
2211
2212
47
    tuple = checked_divmod(pyus, CONST_US_PER_SECOND(st));
2213
47
    if (tuple == NULL) {
2214
0
        goto Done;
2215
0
    }
2216
2217
47
    num = PyTuple_GET_ITEM(tuple, 1);           /* us */
2218
47
    us = PyLong_AsInt(num);
2219
47
    num = NULL;
2220
47
    if (us == -1 && PyErr_Occurred()) {
2221
0
        goto Done;
2222
0
    }
2223
47
    if (!(0 <= us && us < 1000000)) {
2224
0
        goto BadDivmod;
2225
0
    }
2226
2227
47
    num = Py_NewRef(PyTuple_GET_ITEM(tuple, 0));        /* leftover seconds */
2228
47
    Py_DECREF(tuple);
2229
2230
47
    tuple = checked_divmod(num, CONST_SEC_PER_DAY(st));
2231
47
    if (tuple == NULL)
2232
0
        goto Done;
2233
47
    Py_DECREF(num);
2234
2235
47
    num = PyTuple_GET_ITEM(tuple, 1);           /* seconds */
2236
47
    s = PyLong_AsInt(num);
2237
47
    num = NULL;
2238
47
    if (s == -1 && PyErr_Occurred()) {
2239
0
        goto Done;
2240
0
    }
2241
47
    if (!(0 <= s && s < 24*3600)) {
2242
0
        goto BadDivmod;
2243
0
    }
2244
2245
47
    num = Py_NewRef(PyTuple_GET_ITEM(tuple, 0));           /* leftover days */
2246
47
    d = PyLong_AsInt(num);
2247
47
    if (d == -1 && PyErr_Occurred()) {
2248
2
        goto Done;
2249
2
    }
2250
45
    result = new_delta_ex(d, s, us, 0, type);
2251
2252
47
Done:
2253
47
    Py_XDECREF(tuple);
2254
47
    Py_XDECREF(num);
2255
47
    RELEASE_CURRENT_STATE(st, current_mod);
2256
47
    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
45
}
2263
2264
#define microseconds_to_delta(pymicros) \
2265
16
    microseconds_to_delta_ex(pymicros, DELTA_TYPE(NO_STATE))
2266
2267
static PyObject *
2268
multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
2269
16
{
2270
16
    PyObject *pyus_in;
2271
16
    PyObject *pyus_out;
2272
16
    PyObject *result;
2273
2274
16
    pyus_in = delta_to_microseconds(delta);
2275
16
    if (pyus_in == NULL)
2276
0
        return NULL;
2277
2278
16
    pyus_out = PyNumber_Multiply(intobj, pyus_in);
2279
16
    Py_DECREF(pyus_in);
2280
16
    if (pyus_out == NULL)
2281
0
        return NULL;
2282
2283
16
    result = microseconds_to_delta(pyus_out);
2284
16
    Py_DECREF(pyus_out);
2285
16
    return result;
2286
16
}
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
2
{
2516
2
    int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2517
2
    if (diff == 0) {
2518
2
        diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2519
2
        if (diff == 0)
2520
2
            diff = GET_TD_MICROSECONDS(self) -
2521
2
                GET_TD_MICROSECONDS(other);
2522
2
    }
2523
2
    return diff;
2524
2
}
2525
2526
static PyObject *
2527
delta_richcompare(PyObject *self, PyObject *other, int op)
2528
2
{
2529
2
    if (PyDelta_Check(other)) {
2530
2
        int diff = delta_cmp(self, other);
2531
2
        return diff_to_bool(diff, op);
2532
2
    }
2533
0
    else {
2534
0
        Py_RETURN_NOTIMPLEMENTED;
2535
0
    }
2536
2
}
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
16
{
2559
16
    PyObject *result = Py_NotImplemented;
2560
2561
16
    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
16
    else if (PyLong_Check(left))
2571
16
        result = multiply_int_timedelta(left,
2572
16
                        (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
16
    if (result == Py_NotImplemented)
2578
0
        Py_INCREF(result);
2579
16
    return result;
2580
16
}
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
31
{
2714
31
    PyObject *prod;
2715
31
    PyObject *sum;
2716
2717
31
    assert(num != NULL);
2718
2719
31
    if (PyLong_Check(num)) {
2720
22
        prod = PyNumber_Multiply(num, factor);
2721
22
        if (prod == NULL)
2722
0
            return NULL;
2723
22
        sum = PyNumber_Add(sofar, prod);
2724
22
        Py_DECREF(prod);
2725
22
        return sum;
2726
22
    }
2727
2728
9
    if (PyFloat_Check(num)) {
2729
9
        double dnum;
2730
9
        double fracpart;
2731
9
        double intpart;
2732
9
        PyObject *x;
2733
9
        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
9
        dnum = PyFloat_AsDouble(num);
2744
9
        if (dnum == -1.0 && PyErr_Occurred())
2745
0
            return NULL;
2746
9
        fracpart = modf(dnum, &intpart);
2747
9
        x = PyLong_FromDouble(intpart);
2748
9
        if (x == NULL)
2749
0
            return NULL;
2750
2751
9
        prod = PyNumber_Multiply(x, factor);
2752
9
        Py_DECREF(x);
2753
9
        if (prod == NULL)
2754
0
            return NULL;
2755
2756
9
        sum = PyNumber_Add(sofar, prod);
2757
9
        Py_DECREF(prod);
2758
9
        if (sum == NULL)
2759
0
            return NULL;
2760
2761
9
        if (fracpart == 0.0)
2762
2
            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
9
        assert(PyLong_CheckExact(factor));
2768
7
        dnum = PyLong_AsDouble(factor);
2769
2770
7
        dnum *= fracpart;
2771
7
        fracpart = modf(dnum, &intpart);
2772
7
        x = PyLong_FromDouble(intpart);
2773
7
        if (x == NULL) {
2774
0
            Py_DECREF(sum);
2775
0
            return NULL;
2776
0
        }
2777
2778
7
        y = PyNumber_Add(sum, x);
2779
7
        Py_DECREF(sum);
2780
7
        Py_DECREF(x);
2781
7
        *leftover += fracpart;
2782
7
        return y;
2783
7
    }
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
9
}
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
31
{
2815
31
    PyObject *self = NULL;
2816
2817
31
    PyObject *current_mod = NULL;
2818
31
    datetime_state *st = GET_CURRENT_STATE(current_mod);
2819
2820
31
    PyObject *x = NULL;         /* running sum of microseconds */
2821
31
    PyObject *y = NULL;         /* temp sum of microseconds */
2822
31
    double leftover_us = 0.0;
2823
2824
31
    x = PyLong_FromLong(0);
2825
31
    if (x == NULL)
2826
0
        goto Done;
2827
2828
31
#define CLEANUP         \
2829
36
    Py_DECREF(x);       \
2830
36
    x = y;              \
2831
36
    if (x == NULL)      \
2832
36
        goto Done
2833
2834
31
    if (microseconds) {
2835
0
        y = accum("microseconds", x, microseconds, _PyLong_GetOne(), &leftover_us);
2836
0
        CLEANUP;
2837
0
    }
2838
31
    if (milliseconds) {
2839
2
        y = accum("milliseconds", x, milliseconds, CONST_US_PER_MS(st), &leftover_us);
2840
2
        CLEANUP;
2841
2
    }
2842
31
    if (seconds) {
2843
25
        y = accum("seconds", x, seconds, CONST_US_PER_SECOND(st), &leftover_us);
2844
25
        CLEANUP;
2845
25
    }
2846
31
    if (minutes) {
2847
0
        y = accum("minutes", x, minutes, CONST_US_PER_MINUTE(st), &leftover_us);
2848
0
        CLEANUP;
2849
0
    }
2850
31
    if (hours) {
2851
0
        y = accum("hours", x, hours, CONST_US_PER_HOUR(st), &leftover_us);
2852
0
        CLEANUP;
2853
0
    }
2854
31
    if (days) {
2855
4
        y = accum("days", x, days, CONST_US_PER_DAY(st), &leftover_us);
2856
4
        CLEANUP;
2857
4
    }
2858
31
    if (weeks) {
2859
0
        y = accum("weeks", x, weeks, CONST_US_PER_WEEK(st), &leftover_us);
2860
0
        CLEANUP;
2861
0
    }
2862
31
    if (leftover_us) {
2863
        /* Round to nearest whole # of us, and add into x. */
2864
5
        double whole_us = round(leftover_us);
2865
5
        int x_is_odd;
2866
5
        PyObject *temp;
2867
2868
5
        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
5
        temp = PyLong_FromLong((long)whole_us);
2889
2890
5
        if (temp == NULL) {
2891
0
            Py_DECREF(x);
2892
0
            goto Done;
2893
0
        }
2894
5
        y = PyNumber_Add(x, temp);
2895
5
        Py_DECREF(temp);
2896
5
        CLEANUP;
2897
5
    }
2898
2899
31
    self = microseconds_to_delta_ex(x, type);
2900
31
    Py_DECREF(x);
2901
2902
31
Done:
2903
31
    RELEASE_CURRENT_STATE(st, current_mod);
2904
31
    return self;
2905
2906
31
#undef CLEANUP
2907
31
}
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
26
{
3009
26
    PyObject *total_seconds;
3010
26
    PyObject *total_microseconds;
3011
3012
26
    total_microseconds = delta_to_microseconds(PyDelta_CAST(op));
3013
26
    if (total_microseconds == NULL)
3014
0
        return NULL;
3015
3016
26
    PyObject *current_mod = NULL;
3017
26
    datetime_state *st = GET_CURRENT_STATE(current_mod);
3018
3019
26
    total_seconds = PyNumber_TrueDivide(total_microseconds, CONST_US_PER_SECOND(st));
3020
3021
26
    RELEASE_CURRENT_STATE(st, current_mod);
3022
26
    Py_DECREF(total_microseconds);
3023
26
    return total_seconds;
3024
26
}
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
307
{
3146
307
    if (days == 0 && seconds == 0 && microseconds == 0
3147
12
            && type == Py_TYPE(&zero_delta))
3148
12
    {
3149
12
        return &zero_delta;
3150
12
    }
3151
295
    return NULL;
3152
307
}
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
5
{
3164
5
    PyDateTime_Date *self = PyDate_CAST(op);
3165
5
    return PyLong_FromLong(GET_YEAR(self));
3166
5
}
3167
3168
static PyObject *
3169
date_month(PyObject *op, void *Py_UNUSED(closure))
3170
5
{
3171
5
    PyDateTime_Date *self = PyDate_CAST(op);
3172
5
    return PyLong_FromLong(GET_MONTH(self));
3173
5
}
3174
3175
static PyObject *
3176
date_day(PyObject *op, void *Py_UNUSED(closure))
3177
5
{
3178
5
    PyDateTime_Date *self = PyDate_CAST(op);
3179
5
    return PyLong_FromLong(GET_DAY(self));
3180
5
}
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
131
{
3208
    /* Check for invocation from pickle with __getstate__ state */
3209
131
    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
131
    return datetime_date(type, args, kw);
3241
131
}
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
131
{
3258
131
    return new_date_ex(year, month, day, type);
3259
131
}
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
96
{
3638
    /* This method can be inherited, and needs to call the
3639
     * timetuple() method appropriate to self's class.
3640
     */
3641
96
    PyObject *result;
3642
96
    PyObject *tuple;
3643
3644
96
    tuple = PyObject_CallMethodNoArgs(self, &_Py_ID(timetuple));
3645
96
    if (tuple == NULL)
3646
0
        return NULL;
3647
96
    result = wrap_strftime(self, format, tuple, self);
3648
96
    Py_DECREF(tuple);
3649
96
    return result;
3650
96
}
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
96
{
3890
96
    return build_struct_time(GET_YEAR(self),
3891
96
                             GET_MONTH(self),
3892
96
                             GET_DAY(self),
3893
96
                             0, 0, 0, -1);
3894
96
}
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
5
{
3917
5
    return Py_HashBuffer(data, len);
3918
5
}
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
2
{
3940
2
    return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3941
2
                                      GET_DAY(self)));
3942
2
}
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
64
{
4556
64
    if (offset == utc_timezone.offset && name == NULL) {
4557
0
        return (PyDateTime_TimeZone *)CONST_UTC(NO_STATE);
4558
0
    }
4559
64
    return NULL;
4560
64
}
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
135
{
4663
    /* Check for invocation from pickle with __getstate__ state */
4664
135
    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
135
    return datetime_time(type, args, kw);
4700
135
}
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
135
{
4725
135
    return new_time_ex2(hour, minute, second, microsecond, tzinfo, fold, type);
4726
135
}
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
135
{
4767
135
    PyDateTime_Time *self = PyTime_CAST(op);
4768
135
    if (HASTZINFO(self)) {
4769
0
        Py_XDECREF(self->tzinfo);
4770
0
    }
4771
135
    Py_TYPE(self)->tp_free(self);
4772
135
}
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
5
{
5350
5
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
5351
5
    return PyLong_FromLong(DATE_GET_HOUR(self));
5352
5
}
5353
5354
static PyObject *
5355
datetime_minute(PyObject *op, void *Py_UNUSED(closure))
5356
5
{
5357
5
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
5358
5
    return PyLong_FromLong(DATE_GET_MINUTE(self));
5359
5
}
5360
5361
static PyObject *
5362
datetime_second(PyObject *op, void *Py_UNUSED(closure))
5363
5
{
5364
5
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
5365
5
    return PyLong_FromLong(DATE_GET_SECOND(self));
5366
5
}
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
50
{
5439
    /* Check for invocation from pickle with __getstate__ state */
5440
50
    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
50
    return datetime_datetime(type, args, kw);
5476
50
}
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
50
{
5505
50
    return new_datetime_ex2(year, month, day,
5506
50
                            hour, minute, second, microsecond,
5507
50
                            tzinfo, fold, type);
5508
50
}
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
0
        long long probe_seconds, result_seconds, transition;
5589
5590
0
        result_seconds = utc_to_seconds(year, month, day,
5591
0
                                        hour, minute, second);
5592
0
        if (result_seconds == -1 && PyErr_Occurred()) {
5593
0
            return NULL;
5594
0
        }
5595
5596
        /* Probe max_fold_seconds to detect a fold. */
5597
0
        probe_seconds = local(epoch + timet - max_fold_seconds);
5598
0
        if (probe_seconds == -1)
5599
0
            return NULL;
5600
0
        transition = result_seconds - probe_seconds - max_fold_seconds;
5601
0
        if (transition < 0) {
5602
0
            probe_seconds = local(epoch + timet + transition);
5603
0
            if (probe_seconds == -1)
5604
0
                return NULL;
5605
0
            if (probe_seconds == result_seconds)
5606
0
                fold = 1;
5607
0
        }
5608
0
    }
5609
0
    return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
5610
0
                                         second, us, tzinfo, fold, cls);
5611
0
}
5612
5613
/* Internal helper.
5614
 * Build datetime from a Python timestamp.  Pass localtime or gmtime for f,
5615
 * to control the interpretation of the timestamp.  Since a double doesn't
5616
 * have enough bits to cover a datetime's full range of precision, it's
5617
 * better to call datetime_from_timet_and_us provided you have a way
5618
 * to get that much precision (e.g., C time() isn't good enough).
5619
 */
5620
static PyObject *
5621
datetime_from_timestamp(PyTypeObject *cls, TM_FUNC f, PyObject *timestamp,
5622
                        PyObject *tzinfo)
5623
0
{
5624
0
    time_t timet;
5625
0
    long us;
5626
5627
0
    if (_PyTime_ObjectToTimeval(timestamp,
5628
0
                                &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
5629
0
        return NULL;
5630
5631
0
    return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
5632
0
}
5633
5634
/* Internal helper.
5635
 * Build most accurate possible datetime for current time.  Pass localtime or
5636
 * gmtime for f as appropriate.
5637
 */
5638
static PyObject *
5639
datetime_best_possible(PyTypeObject *cls, TM_FUNC f, PyObject *tzinfo)
5640
0
{
5641
0
    PyTime_t ts;
5642
0
    if (PyTime_Time(&ts) < 0) {
5643
0
        return NULL;
5644
0
    }
5645
5646
0
    time_t secs;
5647
0
    int us;
5648
5649
0
    if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_HALF_EVEN) < 0) {
5650
0
        return NULL;
5651
0
    }
5652
0
    assert(0 <= us && us <= 999999);
5653
5654
0
    return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
5655
0
}
5656
5657
/*[clinic input]
5658
5659
@classmethod
5660
datetime.datetime.now
5661
5662
    tz: object = None
5663
        Timezone object.
5664
5665
Returns new datetime object representing current time local to tz.
5666
5667
If no tz is specified, uses local timezone.
5668
[clinic start generated code]*/
5669
5670
static PyObject *
5671
datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
5672
/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
5673
0
{
5674
0
    PyObject *self;
5675
5676
    /* Return best possible local time -- this isn't constrained by the
5677
     * precision of a timestamp.
5678
     */
5679
0
    if (check_tzinfo_subclass(tz) < 0)
5680
0
        return NULL;
5681
5682
0
    self = datetime_best_possible(type,
5683
0
                                  tz == Py_None ? _PyTime_localtime :
5684
0
                                  _PyTime_gmtime,
5685
0
                                  tz);
5686
0
    if (self != NULL && tz != Py_None) {
5687
        /* Convert UTC to tzinfo's zone. */
5688
0
        PyObject *res = PyObject_CallMethodOneArg(tz, &_Py_ID(fromutc), self);
5689
0
        Py_DECREF(self);
5690
0
        return res;
5691
0
    }
5692
0
    return self;
5693
0
}
5694
5695
/* Return best possible UTC time -- this isn't constrained by the
5696
 * precision of a timestamp.
5697
 */
5698
/*[clinic input]
5699
@classmethod
5700
datetime.datetime.utcnow
5701
5702
Return a new datetime representing UTC day and time.
5703
[clinic start generated code]*/
5704
5705
static PyObject *
5706
datetime_datetime_utcnow_impl(PyTypeObject *type)
5707
/*[clinic end generated code: output=cfcfe71c6c916ba9 input=576eff2b222b80a1]*/
5708
0
{
5709
0
    if (PyErr_WarnEx(PyExc_DeprecationWarning,
5710
0
        "datetime.datetime.utcnow() is deprecated and scheduled for removal in a "
5711
0
        "future version. Use timezone-aware objects to represent datetimes "
5712
0
        "in UTC: datetime.datetime.now(datetime.UTC).", 1))
5713
0
    {
5714
0
        return NULL;
5715
0
    }
5716
0
    return datetime_best_possible(type, _PyTime_gmtime, Py_None);
5717
0
}
5718
5719
/*[clinic input]
5720
@permit_long_docstring_body
5721
@classmethod
5722
datetime.datetime.fromtimestamp
5723
5724
    timestamp: object
5725
    tz as tzinfo: object = None
5726
5727
Create a datetime from a POSIX timestamp.
5728
5729
The timestamp is a number, e.g. created via time.time(), that is interpreted
5730
as local time.
5731
[clinic start generated code]*/
5732
5733
static PyObject *
5734
datetime_datetime_fromtimestamp_impl(PyTypeObject *type, PyObject *timestamp,
5735
                                     PyObject *tzinfo)
5736
/*[clinic end generated code: output=9c47ea2b2ebdaded input=d6b5b2095c5a34b2]*/
5737
0
{
5738
0
    PyObject *self;
5739
0
    if (check_tzinfo_subclass(tzinfo) < 0)
5740
0
        return NULL;
5741
5742
0
    self = datetime_from_timestamp(type,
5743
0
                                   tzinfo == Py_None ? _PyTime_localtime :
5744
0
                                   _PyTime_gmtime,
5745
0
                                   timestamp,
5746
0
                                   tzinfo);
5747
0
    if (self != NULL && tzinfo != Py_None) {
5748
        /* Convert UTC to tzinfo's zone. */
5749
0
        PyObject *res = PyObject_CallMethodOneArg(tzinfo, &_Py_ID(fromutc), self);
5750
0
        Py_DECREF(self);
5751
0
        return res;
5752
0
    }
5753
0
    return self;
5754
0
}
5755
5756
/* This is a wrapper for API compatibility with the public C API. */
5757
static PyObject *
5758
datetime_datetime_fromtimestamp_capi(PyObject *cls, PyObject *args, PyObject *kw)
5759
0
{
5760
0
    PyObject *timestamp;
5761
0
    PyObject *tzinfo = Py_None;
5762
0
    static char *keywords[] = {"timestamp", "tz", NULL};
5763
5764
0
    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
5765
0
                                     keywords, &timestamp, &tzinfo))
5766
0
        return NULL;
5767
0
    return datetime_datetime_fromtimestamp_impl((PyTypeObject *)cls,
5768
0
                                                timestamp, tzinfo);
5769
0
}
5770
5771
/*[clinic input]
5772
@classmethod
5773
datetime.datetime.utcfromtimestamp
5774
5775
    timestamp: object
5776
    /
5777
5778
Create a naive UTC datetime from a POSIX timestamp.
5779
[clinic start generated code]*/
5780
5781
static PyObject *
5782
datetime_datetime_utcfromtimestamp_impl(PyTypeObject *type,
5783
                                        PyObject *timestamp)
5784
/*[clinic end generated code: output=66d0b1741d788fd2 input=13fabd4296b1c206]*/
5785
0
{
5786
0
    if (PyErr_WarnEx(PyExc_DeprecationWarning,
5787
0
        "datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal "
5788
0
        "in a future version. Use timezone-aware objects to represent "
5789
0
        "datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC).", 1))
5790
0
    {
5791
0
        return NULL;
5792
0
    }
5793
5794
0
    return datetime_from_timestamp(type, _PyTime_gmtime, timestamp, Py_None);
5795
0
}
5796
5797
/*[clinic input]
5798
@permit_long_summary
5799
@classmethod
5800
datetime.datetime.strptime
5801
5802
    string: unicode
5803
    format: unicode
5804
    /
5805
5806
Parse string according to the given date and time format (like time.strptime()).
5807
5808
For a list of supported format codes, see the documentation:
5809
    https://docs.python.org/3/library/datetime.html#format-codes
5810
[clinic start generated code]*/
5811
5812
static PyObject *
5813
datetime_datetime_strptime_impl(PyTypeObject *type, PyObject *string,
5814
                                PyObject *format)
5815
/*[clinic end generated code: output=af2c2d024f3203f5 input=ef7807589f1d50e7]*/
5816
0
{
5817
0
    PyObject *result;
5818
5819
0
    PyObject *module = PyImport_Import(&_Py_ID(_strptime));
5820
0
    if (module == NULL) {
5821
0
        return NULL;
5822
0
    }
5823
0
    result = PyObject_CallMethodObjArgs(module,
5824
0
                                        &_Py_ID(_strptime_datetime_datetime),
5825
0
                                        (PyObject *)type, string, format, NULL);
5826
0
    Py_DECREF(module);
5827
0
    return result;
5828
0
}
5829
5830
/*[clinic input]
5831
@classmethod
5832
datetime.datetime.combine
5833
5834
    date: object(subclass_of="DATE_TYPE(NO_STATE)")
5835
    time: object(subclass_of="TIME_TYPE(NO_STATE)")
5836
    tzinfo: object = NULL
5837
5838
Construct a datetime from a given date and a given time.
5839
[clinic start generated code]*/
5840
5841
static PyObject *
5842
datetime_datetime_combine_impl(PyTypeObject *type, PyObject *date,
5843
                               PyObject *time, PyObject *tzinfo)
5844
/*[clinic end generated code: output=a10f3cbb90f4d0aa input=4fcf0743288d0bab]*/
5845
0
{
5846
0
    if (tzinfo == NULL) {
5847
0
        if (HASTZINFO(time))
5848
0
            tzinfo = ((PyDateTime_Time *)time)->tzinfo;
5849
0
        else
5850
0
            tzinfo = Py_None;
5851
0
    }
5852
0
    return new_datetime_subclass_fold_ex(GET_YEAR(date),
5853
0
                                         GET_MONTH(date),
5854
0
                                         GET_DAY(date),
5855
0
                                         TIME_GET_HOUR(time),
5856
0
                                         TIME_GET_MINUTE(time),
5857
0
                                         TIME_GET_SECOND(time),
5858
0
                                         TIME_GET_MICROSECOND(time),
5859
0
                                         tzinfo,
5860
0
                                         TIME_GET_FOLD(time),
5861
0
                                         type);
5862
0
}
5863
5864
static PyObject *
5865
_sanitize_isoformat_str(PyObject *dtstr)
5866
0
{
5867
0
    Py_ssize_t len = PyUnicode_GetLength(dtstr);
5868
0
    if (len < 7) {  // All valid ISO 8601 strings are at least 7 characters long
5869
0
        return NULL;
5870
0
    }
5871
5872
    // `fromisoformat` allows surrogate characters in exactly one position,
5873
    // the separator; to allow datetime_fromisoformat to make the simplifying
5874
    // assumption that all valid strings can be encoded in UTF-8, this function
5875
    // replaces any surrogate character separators with `T`.
5876
    //
5877
    // The result of this, if not NULL, returns a new reference
5878
0
    const void* const unicode_data = PyUnicode_DATA(dtstr);
5879
0
    const int kind = PyUnicode_KIND(dtstr);
5880
5881
    // Depending on the format of the string, the separator can only ever be
5882
    // in positions 7, 8 or 10. We'll check each of these for a surrogate and
5883
    // if we find one, replace it with `T`. If there is more than one surrogate,
5884
    // we don't have to bother sanitizing it, because the function will later
5885
    // fail when we try to encode the string as ASCII.
5886
0
    static const size_t potential_separators[3] = {7, 8, 10};
5887
0
    size_t surrogate_separator = 0;
5888
0
    for(size_t idx = 0;
5889
0
         idx < sizeof(potential_separators) / sizeof(*potential_separators);
5890
0
         ++idx) {
5891
0
        size_t pos = potential_separators[idx];
5892
0
        if (pos > (size_t)len) {
5893
0
            break;
5894
0
        }
5895
5896
0
        if(Py_UNICODE_IS_SURROGATE(PyUnicode_READ(kind, unicode_data, pos))) {
5897
0
            surrogate_separator = pos;
5898
0
            break;
5899
0
        }
5900
0
    }
5901
5902
0
    if (surrogate_separator == 0) {
5903
0
        return Py_NewRef(dtstr);
5904
0
    }
5905
5906
0
    PyObject *str_out = _PyUnicode_Copy(dtstr);
5907
0
    if (str_out == NULL) {
5908
0
        return NULL;
5909
0
    }
5910
5911
0
    if (PyUnicode_WriteChar(str_out, surrogate_separator, (Py_UCS4)'T')) {
5912
0
        Py_DECREF(str_out);
5913
0
        return NULL;
5914
0
    }
5915
5916
0
    return str_out;
5917
0
}
5918
5919
5920
static Py_ssize_t
5921
0
_find_isoformat_datetime_separator(const char *dtstr, Py_ssize_t len) {
5922
    // The valid date formats can all be distinguished by characters 4 and 5
5923
    // and further narrowed down by character
5924
    // which tells us where to look for the separator character.
5925
    // Format    |  As-rendered |   Position
5926
    // ---------------------------------------
5927
    // %Y-%m-%d  |  YYYY-MM-DD  |    10
5928
    // %Y%m%d    |  YYYYMMDD    |     8
5929
    // %Y-W%V    |  YYYY-Www    |     8
5930
    // %YW%V     |  YYYYWww     |     7
5931
    // %Y-W%V-%u |  YYYY-Www-d  |    10
5932
    // %YW%V%u   |  YYYYWwwd    |     8
5933
    // %Y-%j     |  YYYY-DDD    |     8
5934
    // %Y%j      |  YYYYDDD     |     7
5935
    //
5936
    // Note that because we allow *any* character for the separator, in the
5937
    // case where character 4 is W, it's not straightforward to determine where
5938
    // the separator is — in the case of YYYY-Www-d, you have actual ambiguity,
5939
    // e.g. 2020-W01-0000 could be YYYY-Www-D0HH or YYYY-Www-HHMM, when the
5940
    // separator character is a number in the former case or a hyphen in the
5941
    // latter case.
5942
    //
5943
    // The case of YYYYWww can be distinguished from YYYYWwwd by tracking ahead
5944
    // to either the end of the string or the first non-numeric character —
5945
    // since the time components all come in pairs YYYYWww#HH can be
5946
    // distinguished from YYYYWwwd#HH by the fact that there will always be an
5947
    // odd number of digits before the first non-digit character in the former
5948
    // case.
5949
0
    static const char date_separator = '-';
5950
0
    static const char week_indicator = 'W';
5951
5952
0
    if (len == 7) {
5953
0
        return 7;
5954
0
    }
5955
5956
0
    if (dtstr[4] == date_separator) {
5957
        // YYYY-???
5958
5959
0
        if (dtstr[5] == week_indicator) {
5960
            // YYYY-W??
5961
5962
0
            if (len < 8) {
5963
0
                return -1;
5964
0
            }
5965
5966
0
            if (len > 8 && dtstr[8] == date_separator) {
5967
                // YYYY-Www-D (10) or YYYY-Www-HH (8)
5968
0
                if (len == 9) { return -1; }
5969
0
                if (len > 10 && is_digit(dtstr[10])) {
5970
                    // This is as far as we'll try to go to resolve the
5971
                    // ambiguity for the moment — if we have YYYY-Www-##, the
5972
                    // separator is either a hyphen at 8 or a number at 10.
5973
                    //
5974
                    // We'll assume it's a hyphen at 8 because it's way more
5975
                    // likely that someone will use a hyphen as a separator
5976
                    // than a number, but at this point it's really best effort
5977
                    // because this is an extension of the spec anyway.
5978
0
                    return 8;
5979
0
                }
5980
5981
0
                return 10;
5982
0
            } else {
5983
                // YYYY-Www (8)
5984
0
                return 8;
5985
0
            }
5986
0
        } else {
5987
            // YYYY-MM-DD (10)
5988
0
            return 10;
5989
0
        }
5990
0
    } else {
5991
        // YYYY???
5992
0
        if (dtstr[4] == week_indicator) {
5993
            // YYYYWww (7) or YYYYWwwd (8)
5994
0
            size_t idx = 7;
5995
0
            for (; idx < (size_t)len; ++idx) {
5996
                // Keep going until we run out of digits.
5997
0
                if (!is_digit(dtstr[idx])) {
5998
0
                    break;
5999
0
                }
6000
0
            }
6001
6002
0
            if (idx < 9) {
6003
0
                return idx;
6004
0
            }
6005
6006
0
            if (idx % 2 == 0) {
6007
                // If the index of the last number is even, it's YYYYWww
6008
0
                return 7;
6009
0
            } else {
6010
0
                return 8;
6011
0
            }
6012
0
        } else {
6013
            // YYYYMMDD (8)
6014
0
            return 8;
6015
0
        }
6016
0
    }
6017
0
}
6018
6019
/*[clinic input]
6020
@classmethod
6021
datetime.datetime.fromisoformat
6022
6023
    string: unicode
6024
    /
6025
6026
Construct a date from a string in ISO 8601 format.
6027
[clinic start generated code]*/
6028
6029
static PyObject *
6030
datetime_datetime_fromisoformat_impl(PyTypeObject *type, PyObject *string)
6031
/*[clinic end generated code: output=1800a952fcab79d9 input=d517b158209ded42]*/
6032
0
{
6033
    // We only need to sanitize this string if the separator is a surrogate
6034
    // character. In the situation where the separator location is ambiguous,
6035
    // we don't have to sanitize it anything because that can only happen when
6036
    // the separator is either '-' or a number. This should mostly be a noop
6037
    // but it makes the reference counting easier if we still sanitize.
6038
0
    PyObject *dtstr_clean = _sanitize_isoformat_str(string);
6039
0
    if (dtstr_clean == NULL) {
6040
0
        goto invalid_string_error;
6041
0
    }
6042
6043
0
    Py_ssize_t len;
6044
0
    const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
6045
6046
0
    if (dt_ptr == NULL) {
6047
0
        if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
6048
            // Encoding errors are invalid string errors at this point
6049
0
            goto invalid_string_error;
6050
0
        }
6051
0
        else {
6052
0
            goto error;
6053
0
        }
6054
0
    }
6055
6056
0
    const Py_ssize_t separator_location = _find_isoformat_datetime_separator(
6057
0
            dt_ptr, len);
6058
6059
6060
0
    const char *p = dt_ptr;
6061
6062
0
    int year = 0, month = 0, day = 0;
6063
0
    int hour = 0, minute = 0, second = 0, microsecond = 0;
6064
0
    int tzoffset = 0, tzusec = 0;
6065
6066
    // date runs up to separator_location
6067
0
    int rv = parse_isoformat_date(p, separator_location, &year, &month, &day);
6068
6069
0
    if (!rv && len > separator_location) {
6070
        // In UTF-8, the length of multi-byte characters is encoded in the MSB
6071
0
        p += separator_location;
6072
0
        if ((p[0] & 0x80) == 0) {
6073
0
            p += 1;
6074
0
        }
6075
0
        else {
6076
0
            switch (p[0] & 0xf0) {
6077
0
                case 0xe0:
6078
0
                    p += 3;
6079
0
                    break;
6080
0
                case 0xf0:
6081
0
                    p += 4;
6082
0
                    break;
6083
0
                default:
6084
0
                    p += 2;
6085
0
                    break;
6086
0
            }
6087
0
        }
6088
6089
0
        len -= (p - dt_ptr);
6090
0
        rv = parse_isoformat_time(p, len, &hour, &minute, &second,
6091
0
                                  &microsecond, &tzoffset, &tzusec);
6092
0
        if (rv == -6) {
6093
0
            goto error;
6094
0
        }
6095
0
    }
6096
0
    if (rv < 0) {
6097
0
        goto invalid_string_error;
6098
0
    }
6099
6100
0
    PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
6101
0
    if (tzinfo == NULL) {
6102
0
        goto error;
6103
0
    }
6104
6105
0
    if ((hour == 24) && (month <= 12))  {
6106
0
        int d_in_month = days_in_month(year, month);
6107
0
        if (day <= d_in_month) {
6108
0
            if (minute == 0 && second == 0 && microsecond == 0) {
6109
                // Calculate midnight of the next day
6110
0
                hour = 0;
6111
0
                day += 1;
6112
0
                if (day > d_in_month) {
6113
0
                    day = 1;
6114
0
                    month += 1;
6115
0
                    if (month > 12) {
6116
0
                        month = 1;
6117
0
                        year += 1;
6118
0
                    }
6119
0
                }
6120
0
            } else {
6121
0
                goto invalid_iso_midnight;
6122
0
            }
6123
0
        }
6124
0
    }
6125
0
    PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
6126
0
                                            second, microsecond, tzinfo, type);
6127
6128
0
    Py_DECREF(tzinfo);
6129
0
    Py_DECREF(dtstr_clean);
6130
0
    return dt;
6131
6132
0
invalid_iso_midnight:
6133
0
    PyErr_SetString(PyExc_ValueError, "minute, second, and microsecond must be 0 when hour is 24");
6134
0
    Py_DECREF(tzinfo);
6135
0
    Py_DECREF(dtstr_clean);
6136
0
    return NULL;
6137
6138
0
invalid_string_error:
6139
0
    PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", string);
6140
6141
0
error:
6142
0
    Py_XDECREF(dtstr_clean);
6143
6144
0
    return NULL;
6145
0
}
6146
6147
/*
6148
 * Destructor.
6149
 */
6150
6151
static void
6152
datetime_dealloc(PyObject *op)
6153
36
{
6154
36
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6155
36
    if (HASTZINFO(self)) {
6156
0
        Py_XDECREF(self->tzinfo);
6157
0
    }
6158
36
    Py_TYPE(self)->tp_free(self);
6159
36
}
6160
6161
/*
6162
 * Indirect access to tzinfo methods.
6163
 */
6164
6165
/* These are all METH_NOARGS, so don't need to check the arglist. */
6166
static PyObject *
6167
5
datetime_utcoffset(PyObject *op, PyObject *Py_UNUSED(dummy)) {
6168
5
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6169
5
    return call_utcoffset(GET_DT_TZINFO(self), op);
6170
5
}
6171
6172
static PyObject *
6173
0
datetime_dst(PyObject *op, PyObject *Py_UNUSED(dummy)) {
6174
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6175
0
    return call_dst(GET_DT_TZINFO(self), op);
6176
0
}
6177
6178
static PyObject *
6179
0
datetime_tzname(PyObject *op, PyObject *Py_UNUSED(dummy)) {
6180
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6181
0
    return call_tzname(GET_DT_TZINFO(self), op);
6182
0
}
6183
6184
/*
6185
 * datetime arithmetic.
6186
 */
6187
6188
/* factor must be 1 (to add) or -1 (to subtract).  The result inherits
6189
 * the tzinfo state of date.
6190
 */
6191
static PyObject *
6192
add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
6193
                       int factor)
6194
5
{
6195
    /* Note that the C-level additions can't overflow, because of
6196
     * invariant bounds on the member values.
6197
     */
6198
5
    int year = GET_YEAR(date);
6199
5
    int month = GET_MONTH(date);
6200
5
    int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
6201
5
    int hour = DATE_GET_HOUR(date);
6202
5
    int minute = DATE_GET_MINUTE(date);
6203
5
    int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
6204
5
    int microsecond = DATE_GET_MICROSECOND(date) +
6205
5
                      GET_TD_MICROSECONDS(delta) * factor;
6206
6207
5
    assert(factor == 1 || factor == -1);
6208
5
    if (normalize_datetime(&year, &month, &day,
6209
5
                           &hour, &minute, &second, &microsecond) < 0) {
6210
0
        return NULL;
6211
0
    }
6212
6213
5
    return new_datetime_subclass_ex(year, month, day,
6214
5
                                    hour, minute, second, microsecond,
6215
5
                                    HASTZINFO(date) ? date->tzinfo : Py_None,
6216
5
                                    Py_TYPE(date));
6217
5
}
6218
6219
static PyObject *
6220
datetime_add(PyObject *left, PyObject *right)
6221
5
{
6222
5
    if (PyDateTime_Check(left)) {
6223
        /* datetime + ??? */
6224
5
        if (PyDelta_Check(right))
6225
            /* datetime + delta */
6226
5
            return add_datetime_timedelta(
6227
5
                            (PyDateTime_DateTime *)left,
6228
5
                            (PyDateTime_Delta *)right,
6229
5
                            1);
6230
5
    }
6231
0
    else if (PyDelta_Check(left)) {
6232
        /* delta + datetime */
6233
0
        return add_datetime_timedelta((PyDateTime_DateTime *) right,
6234
0
                                      (PyDateTime_Delta *) left,
6235
0
                                      1);
6236
0
    }
6237
5
    Py_RETURN_NOTIMPLEMENTED;
6238
5
}
6239
6240
static PyObject *
6241
datetime_subtract(PyObject *left, PyObject *right)
6242
6
{
6243
6
    PyObject *result = Py_NotImplemented;
6244
6245
6
    if (PyDateTime_Check(left)) {
6246
        /* datetime - ??? */
6247
6
        if (PyDateTime_Check(right)) {
6248
            /* datetime - datetime */
6249
6
            PyObject *offset1, *offset2, *offdiff = NULL;
6250
6
            int delta_d, delta_s, delta_us;
6251
6252
6
            if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
6253
6
                offset1 = Py_NewRef(Py_None);
6254
6
                offset2 = Py_NewRef(Py_None);
6255
6
            }
6256
0
            else {
6257
0
                offset1 = datetime_utcoffset(left, NULL);
6258
0
                if (offset1 == NULL)
6259
0
                    return NULL;
6260
0
                offset2 = datetime_utcoffset(right, NULL);
6261
0
                if (offset2 == NULL) {
6262
0
                    Py_DECREF(offset1);
6263
0
                    return NULL;
6264
0
                }
6265
0
                if ((offset1 != Py_None) != (offset2 != Py_None)) {
6266
0
                    PyErr_SetString(PyExc_TypeError,
6267
0
                                    "can't subtract offset-naive and "
6268
0
                                    "offset-aware datetimes");
6269
0
                    Py_DECREF(offset1);
6270
0
                    Py_DECREF(offset2);
6271
0
                    return NULL;
6272
0
                }
6273
0
            }
6274
6
            if ((offset1 != offset2) &&
6275
0
                delta_cmp(offset1, offset2) != 0) {
6276
0
                offdiff = delta_subtract(offset1, offset2);
6277
0
                if (offdiff == NULL) {
6278
0
                    Py_DECREF(offset1);
6279
0
                    Py_DECREF(offset2);
6280
0
                    return NULL;
6281
0
                }
6282
0
            }
6283
6
            Py_DECREF(offset1);
6284
6
            Py_DECREF(offset2);
6285
6
            delta_d = ymd_to_ord(GET_YEAR(left),
6286
6
                                 GET_MONTH(left),
6287
6
                                 GET_DAY(left)) -
6288
6
                      ymd_to_ord(GET_YEAR(right),
6289
6
                                 GET_MONTH(right),
6290
6
                                 GET_DAY(right));
6291
            /* These can't overflow, since the values are
6292
             * normalized.  At most this gives the number of
6293
             * seconds in one day.
6294
             */
6295
6
            delta_s = (DATE_GET_HOUR(left) -
6296
6
                       DATE_GET_HOUR(right)) * 3600 +
6297
6
                      (DATE_GET_MINUTE(left) -
6298
6
                       DATE_GET_MINUTE(right)) * 60 +
6299
6
                      (DATE_GET_SECOND(left) -
6300
6
                       DATE_GET_SECOND(right));
6301
6
            delta_us = DATE_GET_MICROSECOND(left) -
6302
6
                       DATE_GET_MICROSECOND(right);
6303
6
            result = new_delta(delta_d, delta_s, delta_us, 1);
6304
6
            if (result == NULL)
6305
0
                return NULL;
6306
6307
6
            if (offdiff != NULL) {
6308
0
                Py_SETREF(result, delta_subtract(result, offdiff));
6309
0
                Py_DECREF(offdiff);
6310
0
            }
6311
6
        }
6312
0
        else if (PyDelta_Check(right)) {
6313
            /* datetime - delta */
6314
0
            result = add_datetime_timedelta(
6315
0
                            (PyDateTime_DateTime *)left,
6316
0
                            (PyDateTime_Delta *)right,
6317
0
                            -1);
6318
0
        }
6319
6
    }
6320
6321
6
    if (result == Py_NotImplemented)
6322
0
        Py_INCREF(result);
6323
6
    return result;
6324
6
}
6325
6326
/* Various ways to turn a datetime into a string. */
6327
6328
static PyObject *
6329
datetime_repr(PyObject *op)
6330
0
{
6331
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6332
0
    const char *type_name = Py_TYPE(self)->tp_name;
6333
0
    PyObject *baserepr;
6334
6335
0
    if (DATE_GET_MICROSECOND(self)) {
6336
0
        baserepr = PyUnicode_FromFormat(
6337
0
                      "%s(%d, %d, %d, %d, %d, %d, %d)",
6338
0
                      type_name,
6339
0
                      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
6340
0
                      DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
6341
0
                      DATE_GET_SECOND(self),
6342
0
                      DATE_GET_MICROSECOND(self));
6343
0
    }
6344
0
    else if (DATE_GET_SECOND(self)) {
6345
0
        baserepr = PyUnicode_FromFormat(
6346
0
                      "%s(%d, %d, %d, %d, %d, %d)",
6347
0
                      type_name,
6348
0
                      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
6349
0
                      DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
6350
0
                      DATE_GET_SECOND(self));
6351
0
    }
6352
0
    else {
6353
0
        baserepr = PyUnicode_FromFormat(
6354
0
                      "%s(%d, %d, %d, %d, %d)",
6355
0
                      type_name,
6356
0
                      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
6357
0
                      DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
6358
0
    }
6359
0
    if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
6360
0
        baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
6361
0
    if (baserepr == NULL || ! HASTZINFO(self))
6362
0
        return baserepr;
6363
0
    return append_keyword_tzinfo(baserepr, self->tzinfo);
6364
0
}
6365
6366
static PyObject *
6367
datetime_str(PyObject *op)
6368
0
{
6369
0
    PyObject *space = PyUnicode_FromString(" ");
6370
0
    if (space == NULL) {
6371
0
        return NULL;
6372
0
    }
6373
0
    PyObject *res = PyObject_CallMethodOneArg(op, &_Py_ID(isoformat), space);
6374
0
    Py_DECREF(space);
6375
0
    return res;
6376
0
}
6377
6378
/*[clinic input]
6379
datetime.datetime.isoformat
6380
6381
    sep: int(accept={str}, c_default="'T'", py_default="'T'") = ord('T')
6382
    timespec: str(c_default="NULL") = 'auto'
6383
6384
Return the time formatted according to ISO.
6385
6386
The full format looks like 'YYYY-MM-DD HH:MM:SS.mmmmmm'.
6387
By default, the fractional part is omitted if self.microsecond == 0.
6388
6389
If self.tzinfo is not None, the UTC offset is also attached, giving
6390
a full format of 'YYYY-MM-DD HH:MM:SS.mmmmmm+HH:MM'.
6391
6392
Optional argument sep specifies the separator between date and
6393
time, default 'T'.
6394
6395
The optional argument timespec specifies the number of additional
6396
terms of the time to include. Valid options are 'auto', 'hours',
6397
'minutes', 'seconds', 'milliseconds' and 'microseconds'.
6398
[clinic start generated code]*/
6399
6400
static PyObject *
6401
datetime_datetime_isoformat_impl(PyDateTime_DateTime *self, int sep,
6402
                                 const char *timespec)
6403
/*[clinic end generated code: output=9b6ce1383189b0bf input=2fa2512172ccf5d5]*/
6404
0
{
6405
0
    char buffer[100];
6406
6407
0
    PyObject *result = NULL;
6408
0
    int us = DATE_GET_MICROSECOND(self);
6409
0
    static const char * const specs[][2] = {
6410
0
        {"hours", "%04d-%02d-%02d%c%02d"},
6411
0
        {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
6412
0
        {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
6413
0
        {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
6414
0
        {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
6415
0
    };
6416
0
    size_t given_spec;
6417
6418
0
    if (timespec == NULL || strcmp(timespec, "auto") == 0) {
6419
0
        if (us == 0) {
6420
            /* seconds */
6421
0
            given_spec = 2;
6422
0
        }
6423
0
        else {
6424
            /* microseconds */
6425
0
            given_spec = 4;
6426
0
        }
6427
0
    }
6428
0
    else {
6429
0
        for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
6430
0
            if (strcmp(timespec, specs[given_spec][0]) == 0) {
6431
0
                if (given_spec == 3) {
6432
0
                    us = us / 1000;
6433
0
                }
6434
0
                break;
6435
0
            }
6436
0
        }
6437
0
    }
6438
6439
0
    if (given_spec == Py_ARRAY_LENGTH(specs)) {
6440
0
        PyErr_Format(PyExc_ValueError, "Unknown timespec value");
6441
0
        return NULL;
6442
0
    }
6443
0
    else {
6444
0
        result = PyUnicode_FromFormat(specs[given_spec][1],
6445
0
                                      GET_YEAR(self), GET_MONTH(self),
6446
0
                                      GET_DAY(self), (int)sep,
6447
0
                                      DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
6448
0
                                      DATE_GET_SECOND(self), us);
6449
0
    }
6450
6451
0
    if (!result || !HASTZINFO(self))
6452
0
        return result;
6453
6454
    /* We need to append the UTC offset. */
6455
0
    if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo, (PyObject *)self) < 0) {
6456
0
        Py_DECREF(result);
6457
0
        return NULL;
6458
0
    }
6459
0
    PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
6460
0
    return result;
6461
0
}
6462
6463
static PyObject *
6464
datetime_ctime(PyObject *op, PyObject *Py_UNUSED(dummy))
6465
0
{
6466
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6467
0
    return format_ctime(op,
6468
0
                        DATE_GET_HOUR(self),
6469
0
                        DATE_GET_MINUTE(self),
6470
0
                        DATE_GET_SECOND(self));
6471
0
}
6472
6473
/* Miscellaneous methods. */
6474
6475
static PyObject *
6476
flip_fold(PyObject *dt)
6477
0
{
6478
0
    return new_datetime_ex2(GET_YEAR(dt),
6479
0
                            GET_MONTH(dt),
6480
0
                            GET_DAY(dt),
6481
0
                            DATE_GET_HOUR(dt),
6482
0
                            DATE_GET_MINUTE(dt),
6483
0
                            DATE_GET_SECOND(dt),
6484
0
                            DATE_GET_MICROSECOND(dt),
6485
0
                            HASTZINFO(dt) ?
6486
0
                             ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
6487
0
                            !DATE_GET_FOLD(dt),
6488
0
                            Py_TYPE(dt));
6489
0
}
6490
6491
static PyObject *
6492
get_flip_fold_offset(PyObject *dt)
6493
0
{
6494
0
    PyObject *result, *flip_dt;
6495
6496
0
    flip_dt = flip_fold(dt);
6497
0
    if (flip_dt == NULL)
6498
0
        return NULL;
6499
0
    result = datetime_utcoffset(flip_dt, NULL);
6500
0
    Py_DECREF(flip_dt);
6501
0
    return result;
6502
0
}
6503
6504
/* PEP 495 exception: Whenever one or both of the operands in
6505
 * inter-zone comparison is such that its utcoffset() depends
6506
 * on the value of its fold attribute, the result is False.
6507
 *
6508
 * Return 1 if exception applies, 0 if not,  and -1 on error.
6509
 */
6510
static int
6511
pep495_eq_exception(PyObject *self, PyObject *other,
6512
                    PyObject *offset_self, PyObject *offset_other)
6513
0
{
6514
0
    int result = 0;
6515
0
    PyObject *flip_offset;
6516
6517
0
    flip_offset = get_flip_fold_offset(self);
6518
0
    if (flip_offset == NULL)
6519
0
        return -1;
6520
0
    if (flip_offset != offset_self &&
6521
0
        delta_cmp(flip_offset, offset_self))
6522
0
    {
6523
0
        result = 1;
6524
0
        goto done;
6525
0
    }
6526
0
    Py_DECREF(flip_offset);
6527
6528
0
    flip_offset = get_flip_fold_offset(other);
6529
0
    if (flip_offset == NULL)
6530
0
        return -1;
6531
0
    if (flip_offset != offset_other &&
6532
0
        delta_cmp(flip_offset, offset_other))
6533
0
        result = 1;
6534
0
 done:
6535
0
    Py_DECREF(flip_offset);
6536
0
    return result;
6537
0
}
6538
6539
static PyObject *
6540
datetime_richcompare(PyObject *self, PyObject *other, int op)
6541
0
{
6542
0
    PyObject *result = NULL;
6543
0
    PyObject *offset1, *offset2;
6544
0
    int diff;
6545
6546
0
    if (!PyDateTime_Check(other)) {
6547
0
        Py_RETURN_NOTIMPLEMENTED;
6548
0
    }
6549
6550
0
    if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
6551
0
        diff = memcmp(((PyDateTime_DateTime *)self)->data,
6552
0
                      ((PyDateTime_DateTime *)other)->data,
6553
0
                      _PyDateTime_DATETIME_DATASIZE);
6554
0
        return diff_to_bool(diff, op);
6555
0
    }
6556
0
    offset1 = datetime_utcoffset(self, NULL);
6557
0
    if (offset1 == NULL)
6558
0
        return NULL;
6559
0
    offset2 = datetime_utcoffset(other, NULL);
6560
0
    if (offset2 == NULL)
6561
0
        goto done;
6562
    /* If they're both naive, or both aware and have the same offsets,
6563
     * we get off cheap.  Note that if they're both naive, offset1 ==
6564
     * offset2 == Py_None at this point.
6565
     */
6566
0
    if ((offset1 == offset2) ||
6567
0
        (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
6568
0
         delta_cmp(offset1, offset2) == 0)) {
6569
0
        diff = memcmp(((PyDateTime_DateTime *)self)->data,
6570
0
                      ((PyDateTime_DateTime *)other)->data,
6571
0
                      _PyDateTime_DATETIME_DATASIZE);
6572
0
        if ((op == Py_EQ || op == Py_NE) && diff == 0) {
6573
0
            int ex = pep495_eq_exception(self, other, offset1, offset2);
6574
0
            if (ex == -1)
6575
0
                goto done;
6576
0
            if (ex)
6577
0
                diff = 1;
6578
0
        }
6579
0
        result = diff_to_bool(diff, op);
6580
0
    }
6581
0
    else if (offset1 != Py_None && offset2 != Py_None) {
6582
0
        PyDateTime_Delta *delta;
6583
6584
0
        assert(offset1 != offset2); /* else last "if" handled it */
6585
0
        delta = (PyDateTime_Delta *)datetime_subtract(self, other);
6586
0
        if (delta == NULL)
6587
0
            goto done;
6588
0
        diff = GET_TD_DAYS(delta);
6589
0
        if (diff == 0)
6590
0
            diff = GET_TD_SECONDS(delta) |
6591
0
                   GET_TD_MICROSECONDS(delta);
6592
0
        Py_DECREF(delta);
6593
0
        if ((op == Py_EQ || op == Py_NE) && diff == 0) {
6594
0
            int ex = pep495_eq_exception(self, other, offset1, offset2);
6595
0
            if (ex == -1)
6596
0
                goto done;
6597
0
            if (ex)
6598
0
                diff = 1;
6599
0
        }
6600
0
        result = diff_to_bool(diff, op);
6601
0
    }
6602
0
    else if (op == Py_EQ) {
6603
0
        result = Py_NewRef(Py_False);
6604
0
    }
6605
0
    else if (op == Py_NE) {
6606
0
        result = Py_NewRef(Py_True);
6607
0
    }
6608
0
    else {
6609
0
        PyErr_SetString(PyExc_TypeError,
6610
0
                        "can't compare offset-naive and "
6611
0
                        "offset-aware datetimes");
6612
0
    }
6613
0
 done:
6614
0
    Py_DECREF(offset1);
6615
0
    Py_XDECREF(offset2);
6616
0
    return result;
6617
0
}
6618
6619
static Py_hash_t
6620
datetime_hash(PyObject *op)
6621
20
{
6622
20
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6623
20
    Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
6624
20
    if (hash == -1) {
6625
5
        PyObject *offset, *self0;
6626
5
        if (DATE_GET_FOLD(self)) {
6627
0
            self0 = new_datetime_ex2(GET_YEAR(self),
6628
0
                                     GET_MONTH(self),
6629
0
                                     GET_DAY(self),
6630
0
                                     DATE_GET_HOUR(self),
6631
0
                                     DATE_GET_MINUTE(self),
6632
0
                                     DATE_GET_SECOND(self),
6633
0
                                     DATE_GET_MICROSECOND(self),
6634
0
                                     HASTZINFO(self) ? self->tzinfo : Py_None,
6635
0
                                     0, Py_TYPE(self));
6636
0
            if (self0 == NULL)
6637
0
                return -1;
6638
0
        }
6639
5
        else {
6640
5
            self0 = Py_NewRef(self);
6641
5
        }
6642
5
        offset = datetime_utcoffset(self0, NULL);
6643
5
        Py_DECREF(self0);
6644
6645
5
        if (offset == NULL)
6646
0
            return -1;
6647
6648
        /* Reduce this to a hash of another object. */
6649
5
        if (offset == Py_None) {
6650
5
            hash = generic_hash(
6651
5
                (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
6652
5
            FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
6653
5
        } else {
6654
0
            PyObject *temp1, *temp2;
6655
0
            int days, seconds;
6656
6657
0
            assert(HASTZINFO(self));
6658
0
            days = ymd_to_ord(GET_YEAR(self),
6659
0
                              GET_MONTH(self),
6660
0
                              GET_DAY(self));
6661
0
            seconds = DATE_GET_HOUR(self) * 3600 +
6662
0
                      DATE_GET_MINUTE(self) * 60 +
6663
0
                      DATE_GET_SECOND(self);
6664
0
            temp1 = new_delta(days, seconds,
6665
0
                              DATE_GET_MICROSECOND(self),
6666
0
                              1);
6667
0
            if (temp1 == NULL) {
6668
0
                Py_DECREF(offset);
6669
0
                return -1;
6670
0
            }
6671
0
            temp2 = delta_subtract(temp1, offset);
6672
0
            Py_DECREF(temp1);
6673
0
            if (temp2 == NULL) {
6674
0
                Py_DECREF(offset);
6675
0
                return -1;
6676
0
            }
6677
0
            hash = PyObject_Hash(temp2);
6678
0
            FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
6679
0
            Py_DECREF(temp2);
6680
0
        }
6681
5
        Py_DECREF(offset);
6682
5
    }
6683
20
    return hash;
6684
20
}
6685
6686
/*[clinic input]
6687
datetime.datetime.replace
6688
6689
    year: int(c_default="GET_YEAR(self)") = unchanged
6690
    month: int(c_default="GET_MONTH(self)") = unchanged
6691
    day: int(c_default="GET_DAY(self)") = unchanged
6692
    hour: int(c_default="DATE_GET_HOUR(self)") = unchanged
6693
    minute: int(c_default="DATE_GET_MINUTE(self)") = unchanged
6694
    second: int(c_default="DATE_GET_SECOND(self)") = unchanged
6695
    microsecond: int(c_default="DATE_GET_MICROSECOND(self)") = unchanged
6696
    tzinfo: object(c_default="HASTZINFO(self) ? ((PyDateTime_DateTime *)self)->tzinfo : Py_None") = unchanged
6697
    *
6698
    fold: int(c_default="DATE_GET_FOLD(self)") = unchanged
6699
6700
Return datetime with new specified fields.
6701
[clinic start generated code]*/
6702
6703
static PyObject *
6704
datetime_datetime_replace_impl(PyDateTime_DateTime *self, int year,
6705
                               int month, int day, int hour, int minute,
6706
                               int second, int microsecond, PyObject *tzinfo,
6707
                               int fold)
6708
/*[clinic end generated code: output=00bc96536833fddb input=fd972762d604d3e7]*/
6709
0
{
6710
0
    return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
6711
0
                                         second, microsecond, tzinfo, fold,
6712
0
                                         Py_TYPE(self));
6713
0
}
6714
6715
static PyObject *
6716
local_timezone_from_timestamp(time_t timestamp)
6717
0
{
6718
0
    PyObject *result = NULL;
6719
0
    PyObject *delta;
6720
0
    struct tm local_time_tm;
6721
0
    PyObject *nameo = NULL;
6722
0
    const char *zone = NULL;
6723
6724
0
    if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
6725
0
        return NULL;
6726
0
#ifdef HAVE_STRUCT_TM_TM_ZONE
6727
0
    zone = local_time_tm.tm_zone;
6728
0
    delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
6729
#else /* HAVE_STRUCT_TM_TM_ZONE */
6730
    {
6731
        PyObject *local_time, *utc_time;
6732
        struct tm utc_time_tm;
6733
        char buf[100];
6734
        strftime(buf, sizeof(buf), "%Z", &local_time_tm);
6735
        zone = buf;
6736
        local_time = new_datetime(local_time_tm.tm_year + 1900,
6737
                                  local_time_tm.tm_mon + 1,
6738
                                  local_time_tm.tm_mday,
6739
                                  local_time_tm.tm_hour,
6740
                                  local_time_tm.tm_min,
6741
                                  local_time_tm.tm_sec, 0, Py_None, 0);
6742
        if (local_time == NULL) {
6743
            return NULL;
6744
        }
6745
        if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
6746
            return NULL;
6747
        utc_time = new_datetime(utc_time_tm.tm_year + 1900,
6748
                                utc_time_tm.tm_mon + 1,
6749
                                utc_time_tm.tm_mday,
6750
                                utc_time_tm.tm_hour,
6751
                                utc_time_tm.tm_min,
6752
                                utc_time_tm.tm_sec, 0, Py_None, 0);
6753
        if (utc_time == NULL) {
6754
            Py_DECREF(local_time);
6755
            return NULL;
6756
        }
6757
        delta = datetime_subtract(local_time, utc_time);
6758
        Py_DECREF(local_time);
6759
        Py_DECREF(utc_time);
6760
    }
6761
#endif /* HAVE_STRUCT_TM_TM_ZONE */
6762
0
    if (delta == NULL) {
6763
0
            return NULL;
6764
0
    }
6765
0
    if (zone != NULL) {
6766
0
        nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
6767
0
        if (nameo == NULL)
6768
0
            goto error;
6769
0
    }
6770
0
    result = new_timezone(delta, nameo);
6771
0
    Py_XDECREF(nameo);
6772
0
  error:
6773
0
    Py_DECREF(delta);
6774
0
    return result;
6775
0
}
6776
6777
static PyObject *
6778
local_timezone(PyDateTime_DateTime *utc_time)
6779
0
{
6780
0
    time_t timestamp;
6781
0
    PyObject *delta;
6782
0
    PyObject *one_second;
6783
0
    PyObject *seconds;
6784
6785
0
    PyObject *current_mod = NULL;
6786
0
    datetime_state *st = GET_CURRENT_STATE(current_mod);
6787
6788
0
    delta = datetime_subtract((PyObject *)utc_time, CONST_EPOCH(st));
6789
0
    RELEASE_CURRENT_STATE(st, current_mod);
6790
0
    if (delta == NULL)
6791
0
        return NULL;
6792
6793
0
    one_second = new_delta(0, 1, 0, 0);
6794
0
    if (one_second == NULL) {
6795
0
        Py_DECREF(delta);
6796
0
        return NULL;
6797
0
    }
6798
0
    seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
6799
0
                                         (PyDateTime_Delta *)one_second);
6800
0
    Py_DECREF(one_second);
6801
0
    Py_DECREF(delta);
6802
0
    if (seconds == NULL)
6803
0
        return NULL;
6804
0
    timestamp = _PyLong_AsTime_t(seconds);
6805
0
    Py_DECREF(seconds);
6806
0
    if (timestamp == -1 && PyErr_Occurred())
6807
0
        return NULL;
6808
0
    return local_timezone_from_timestamp(timestamp);
6809
0
}
6810
6811
static long long
6812
local_to_seconds(int year, int month, int day,
6813
                 int hour, int minute, int second, int fold);
6814
6815
static PyObject *
6816
local_timezone_from_local(PyDateTime_DateTime *local_dt)
6817
0
{
6818
0
    long long seconds, seconds2;
6819
0
    time_t timestamp;
6820
0
    int fold = DATE_GET_FOLD(local_dt);
6821
0
    seconds = local_to_seconds(GET_YEAR(local_dt),
6822
0
                               GET_MONTH(local_dt),
6823
0
                               GET_DAY(local_dt),
6824
0
                               DATE_GET_HOUR(local_dt),
6825
0
                               DATE_GET_MINUTE(local_dt),
6826
0
                               DATE_GET_SECOND(local_dt),
6827
0
                               fold);
6828
0
    if (seconds == -1)
6829
0
        return NULL;
6830
0
    seconds2 = local_to_seconds(GET_YEAR(local_dt),
6831
0
                                GET_MONTH(local_dt),
6832
0
                                GET_DAY(local_dt),
6833
0
                                DATE_GET_HOUR(local_dt),
6834
0
                                DATE_GET_MINUTE(local_dt),
6835
0
                                DATE_GET_SECOND(local_dt),
6836
0
                                !fold);
6837
0
    if (seconds2 == -1)
6838
0
        return NULL;
6839
    /* Detect gap */
6840
0
    if (seconds2 != seconds && (seconds2 > seconds) == fold)
6841
0
        seconds = seconds2;
6842
6843
    /* XXX: add bounds check */
6844
0
    timestamp = seconds - epoch;
6845
0
    return local_timezone_from_timestamp(timestamp);
6846
0
}
6847
6848
/*[clinic input]
6849
datetime.datetime.astimezone
6850
6851
    tz as tzinfo: object = None
6852
6853
Convert to local time in new timezone tz.
6854
[clinic start generated code]*/
6855
6856
static PyObject *
6857
datetime_datetime_astimezone_impl(PyDateTime_DateTime *self,
6858
                                  PyObject *tzinfo)
6859
/*[clinic end generated code: output=ae2263d04e944537 input=9c675c8595009935]*/
6860
0
{
6861
0
    PyDateTime_DateTime *result;
6862
0
    PyObject *offset;
6863
0
    PyObject *temp;
6864
0
    PyObject *self_tzinfo;
6865
6866
0
    if (check_tzinfo_subclass(tzinfo) == -1)
6867
0
        return NULL;
6868
6869
0
    if (!HASTZINFO(self) || self->tzinfo == Py_None) {
6870
0
  naive:
6871
0
        self_tzinfo = local_timezone_from_local(self);
6872
0
        if (self_tzinfo == NULL)
6873
0
            return NULL;
6874
0
    } else {
6875
0
        self_tzinfo = Py_NewRef(self->tzinfo);
6876
0
    }
6877
6878
    /* Conversion to self's own time zone is a NOP. */
6879
0
    if (self_tzinfo == tzinfo) {
6880
0
        Py_DECREF(self_tzinfo);
6881
0
        return Py_NewRef(self);
6882
0
    }
6883
6884
    /* Convert self to UTC. */
6885
0
    offset = call_utcoffset(self_tzinfo, (PyObject *)self);
6886
0
    Py_DECREF(self_tzinfo);
6887
0
    if (offset == NULL)
6888
0
        return NULL;
6889
0
    else if(offset == Py_None) {
6890
0
        Py_DECREF(offset);
6891
0
        goto naive;
6892
0
    }
6893
0
    else if (!PyDelta_Check(offset)) {
6894
0
        Py_DECREF(offset);
6895
0
        PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
6896
0
                     " expected timedelta or None", Py_TYPE(offset)->tp_name);
6897
0
        return NULL;
6898
0
    }
6899
    /* result = self - offset */
6900
0
    result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6901
0
                                       (PyDateTime_Delta *)offset, -1);
6902
0
    Py_DECREF(offset);
6903
0
    if (result == NULL)
6904
0
        return NULL;
6905
6906
    /* Make sure result is aware and UTC. */
6907
0
    if (!HASTZINFO(result)) {
6908
0
        temp = (PyObject *)result;
6909
0
        result = (PyDateTime_DateTime *)
6910
0
                   new_datetime_ex2(GET_YEAR(result),
6911
0
                                    GET_MONTH(result),
6912
0
                                    GET_DAY(result),
6913
0
                                    DATE_GET_HOUR(result),
6914
0
                                    DATE_GET_MINUTE(result),
6915
0
                                    DATE_GET_SECOND(result),
6916
0
                                    DATE_GET_MICROSECOND(result),
6917
0
                                    CONST_UTC(NO_STATE),
6918
0
                                    DATE_GET_FOLD(result),
6919
0
                                    Py_TYPE(result));
6920
0
        Py_DECREF(temp);
6921
0
        if (result == NULL)
6922
0
            return NULL;
6923
0
    }
6924
0
    else {
6925
        /* Result is already aware - just replace tzinfo. */
6926
0
        Py_SETREF(result->tzinfo, Py_NewRef(CONST_UTC(NO_STATE)));
6927
0
    }
6928
6929
    /* Attach new tzinfo and let fromutc() do the rest. */
6930
0
    if (tzinfo == Py_None) {
6931
0
        tzinfo = local_timezone(result);
6932
0
        if (tzinfo == NULL) {
6933
0
            Py_DECREF(result);
6934
0
            return NULL;
6935
0
        }
6936
0
    }
6937
0
    else
6938
0
      Py_INCREF(tzinfo);
6939
0
    Py_SETREF(result->tzinfo, tzinfo);
6940
6941
0
    temp = (PyObject *)result;
6942
0
    result = (PyDateTime_DateTime *)
6943
0
        PyObject_CallMethodOneArg(tzinfo, &_Py_ID(fromutc), temp);
6944
0
    Py_DECREF(temp);
6945
6946
0
    return (PyObject *)result;
6947
0
}
6948
6949
static PyObject *
6950
datetime_timetuple(PyObject *op, PyObject *Py_UNUSED(dummy))
6951
0
{
6952
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
6953
0
    int dstflag = -1;
6954
6955
0
    if (HASTZINFO(self) && self->tzinfo != Py_None) {
6956
0
        PyObject * dst;
6957
6958
0
        dst = call_dst(self->tzinfo, op);
6959
0
        if (dst == NULL)
6960
0
            return NULL;
6961
6962
0
        if (dst != Py_None)
6963
0
            dstflag = delta_bool(dst);
6964
0
        Py_DECREF(dst);
6965
0
    }
6966
0
    return build_struct_time(GET_YEAR(self),
6967
0
                             GET_MONTH(self),
6968
0
                             GET_DAY(self),
6969
0
                             DATE_GET_HOUR(self),
6970
0
                             DATE_GET_MINUTE(self),
6971
0
                             DATE_GET_SECOND(self),
6972
0
                             dstflag);
6973
0
}
6974
6975
static long long
6976
local_to_seconds(int year, int month, int day,
6977
                 int hour, int minute, int second, int fold)
6978
0
{
6979
0
    long long t, a, b, u1, u2, t1, t2, lt;
6980
0
    t = utc_to_seconds(year, month, day, hour, minute, second);
6981
    /* Our goal is to solve t = local(u) for u. */
6982
0
    lt = local(t);
6983
0
    if (lt == -1)
6984
0
        return -1;
6985
0
    a = lt - t;
6986
0
    u1 = t - a;
6987
0
    t1 = local(u1);
6988
0
    if (t1 == -1)
6989
0
        return -1;
6990
0
    if (t1 == t) {
6991
        /* We found one solution, but it may not be the one we need.
6992
         * Look for an earlier solution (if `fold` is 0), or a
6993
         * later one (if `fold` is 1). */
6994
0
        if (fold)
6995
0
            u2 = u1 + max_fold_seconds;
6996
0
        else
6997
0
            u2 = u1 - max_fold_seconds;
6998
0
        lt = local(u2);
6999
0
        if (lt == -1)
7000
0
            return -1;
7001
0
        b = lt - u2;
7002
0
        if (a == b)
7003
0
            return u1;
7004
0
    }
7005
0
    else {
7006
0
        b = t1 - u1;
7007
0
        assert(a != b);
7008
0
    }
7009
0
    u2 = t - b;
7010
0
    t2 = local(u2);
7011
0
    if (t2 == -1)
7012
0
        return -1;
7013
0
    if (t2 == t)
7014
0
        return u2;
7015
0
    if (t1 == t)
7016
0
        return u1;
7017
    /* We have found both offsets a and b, but neither t - a nor t - b is
7018
     * a solution.  This means t is in the gap. */
7019
0
    return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
7020
0
}
7021
7022
/* date(1970,1,1).toordinal() == 719163 */
7023
0
#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
7024
7025
static PyObject *
7026
datetime_timestamp(PyObject *op, PyObject *Py_UNUSED(dummy))
7027
0
{
7028
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
7029
0
    PyObject *result;
7030
7031
0
    if (HASTZINFO(self) && self->tzinfo != Py_None) {
7032
0
        PyObject *current_mod = NULL;
7033
0
        datetime_state *st = GET_CURRENT_STATE(current_mod);
7034
7035
0
        PyObject *delta;
7036
0
        delta = datetime_subtract(op, CONST_EPOCH(st));
7037
0
        RELEASE_CURRENT_STATE(st, current_mod);
7038
0
        if (delta == NULL)
7039
0
            return NULL;
7040
0
        result = delta_total_seconds(delta, NULL);
7041
0
        Py_DECREF(delta);
7042
0
    }
7043
0
    else {
7044
0
        long long seconds;
7045
0
        seconds = local_to_seconds(GET_YEAR(self),
7046
0
                                   GET_MONTH(self),
7047
0
                                   GET_DAY(self),
7048
0
                                   DATE_GET_HOUR(self),
7049
0
                                   DATE_GET_MINUTE(self),
7050
0
                                   DATE_GET_SECOND(self),
7051
0
                                   DATE_GET_FOLD(self));
7052
0
        if (seconds == -1)
7053
0
            return NULL;
7054
0
        result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
7055
0
                                    DATE_GET_MICROSECOND(self) / 1e6);
7056
0
    }
7057
0
    return result;
7058
0
}
7059
7060
static PyObject *
7061
datetime_getdate(PyObject *op, PyObject *Py_UNUSED(dummy))
7062
0
{
7063
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
7064
0
    return new_date(GET_YEAR(self),
7065
0
                    GET_MONTH(self),
7066
0
                    GET_DAY(self));
7067
0
}
7068
7069
static PyObject *
7070
datetime_gettime(PyObject *op, PyObject *Py_UNUSED(dummy))
7071
0
{
7072
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
7073
0
    return new_time(DATE_GET_HOUR(self),
7074
0
                    DATE_GET_MINUTE(self),
7075
0
                    DATE_GET_SECOND(self),
7076
0
                    DATE_GET_MICROSECOND(self),
7077
0
                    Py_None,
7078
0
                    DATE_GET_FOLD(self));
7079
0
}
7080
7081
static PyObject *
7082
datetime_gettimetz(PyObject *op, PyObject *Py_UNUSED(dummy))
7083
0
{
7084
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
7085
0
    return new_time(DATE_GET_HOUR(self),
7086
0
                    DATE_GET_MINUTE(self),
7087
0
                    DATE_GET_SECOND(self),
7088
0
                    DATE_GET_MICROSECOND(self),
7089
0
                    GET_DT_TZINFO(self),
7090
0
                    DATE_GET_FOLD(self));
7091
0
}
7092
7093
static PyObject *
7094
datetime_utctimetuple(PyObject *op, PyObject *Py_UNUSED(dummy))
7095
0
{
7096
0
    int y, m, d, hh, mm, ss;
7097
0
    PyObject *tzinfo;
7098
0
    PyDateTime_DateTime *utcself;
7099
0
    PyDateTime_DateTime *self = PyDateTime_CAST(op);
7100
7101
0
    tzinfo = GET_DT_TZINFO(self);
7102
0
    if (tzinfo == Py_None) {
7103
0
        utcself = (PyDateTime_DateTime*)Py_NewRef(self);
7104
0
    }
7105
0
    else {
7106
0
        PyObject *offset;
7107
0
        offset = call_utcoffset(tzinfo, (PyObject *)self);
7108
0
        if (offset == NULL)
7109
0
            return NULL;
7110
0
        if (offset == Py_None) {
7111
0
            Py_DECREF(offset);
7112
0
            utcself = (PyDateTime_DateTime*)Py_NewRef(self);
7113
0
        }
7114
0
        else {
7115
0
            utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
7116
0
                                                (PyDateTime_Delta *)offset, -1);
7117
0
            Py_DECREF(offset);
7118
0
            if (utcself == NULL)
7119
0
                return NULL;
7120
0
        }
7121
0
    }
7122
0
    y = GET_YEAR(utcself);
7123
0
    m = GET_MONTH(utcself);
7124
0
    d = GET_DAY(utcself);
7125
0
    hh = DATE_GET_HOUR(utcself);
7126
0
    mm = DATE_GET_MINUTE(utcself);
7127
0
    ss = DATE_GET_SECOND(utcself);
7128
7129
0
    Py_DECREF(utcself);
7130
0
    return build_struct_time(y, m, d, hh, mm, ss, 0);
7131
0
}
7132
7133
/* Pickle support, a simple use of __reduce__. */
7134
7135
/* Let basestate be the non-tzinfo data string.
7136
 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
7137
 * So it's a tuple in any (non-error) case.
7138
 * __getstate__ isn't exposed.
7139
 */
7140
static PyObject *
7141
datetime_getstate(PyDateTime_DateTime *self, int proto)
7142
0
{
7143
0
    PyObject *basestate;
7144
0
    PyObject *result = NULL;
7145
7146
0
    basestate = PyBytes_FromStringAndSize((char *)self->data,
7147
0
                                           _PyDateTime_DATETIME_DATASIZE);
7148
0
    if (basestate != NULL) {
7149
0
        if (proto > 3 && DATE_GET_FOLD(self))
7150
            /* Set the first bit of the third byte */
7151
0
            PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
7152
0
        if (! HASTZINFO(self) || self->tzinfo == Py_None)
7153
0
            result = PyTuple_Pack(1, basestate);
7154
0
        else
7155
0
            result = PyTuple_Pack(2, basestate, self->tzinfo);
7156
0
        Py_DECREF(basestate);
7157
0
    }
7158
0
    return result;
7159
0
}
7160
7161
/*[clinic input]
7162
datetime.datetime.__reduce_ex__
7163
7164
    proto: int
7165
    /
7166
[clinic start generated code]*/
7167
7168
static PyObject *
7169
datetime_datetime___reduce_ex___impl(PyDateTime_DateTime *self, int proto)
7170
/*[clinic end generated code: output=53d712ce3e927735 input=bab748e49ffb30c3]*/
7171
0
{
7172
0
    return Py_BuildValue("(ON)", Py_TYPE(self),
7173
0
                         datetime_getstate(self, proto));
7174
0
}
7175
7176
/*[clinic input]
7177
datetime.datetime.__reduce__
7178
[clinic start generated code]*/
7179
7180
static PyObject *
7181
datetime_datetime___reduce___impl(PyDateTime_DateTime *self)
7182
/*[clinic end generated code: output=6794df9ea75666cf input=cadbbeb3bf3bf94c]*/
7183
0
{
7184
0
    return Py_BuildValue("(ON)", Py_TYPE(self),
7185
0
                         datetime_getstate(self, 2));
7186
0
}
7187
7188
static PyMethodDef datetime_methods[] = {
7189
7190
    /* Class methods: */
7191
7192
    DATETIME_DATETIME_NOW_METHODDEF
7193
    DATETIME_DATETIME_UTCNOW_METHODDEF
7194
    DATETIME_DATETIME_FROMTIMESTAMP_METHODDEF
7195
    DATETIME_DATETIME_UTCFROMTIMESTAMP_METHODDEF
7196
    DATETIME_DATETIME_STRPTIME_METHODDEF
7197
    DATETIME_DATETIME_COMBINE_METHODDEF
7198
    DATETIME_DATETIME_FROMISOFORMAT_METHODDEF
7199
7200
    /* Instance methods: */
7201
7202
    {"date", datetime_getdate, METH_NOARGS,
7203
     PyDoc_STR("Return date object with same year, month and day.")},
7204
7205
    {"time", datetime_gettime, METH_NOARGS,
7206
     PyDoc_STR("Return time object with same time but with tzinfo=None.")},
7207
7208
    {"timetz", datetime_gettimetz, METH_NOARGS,
7209
     PyDoc_STR("Return time object with same time and tzinfo.")},
7210
7211
    {"ctime", datetime_ctime, METH_NOARGS,
7212
     PyDoc_STR("Return ctime() style string.")},
7213
7214
    {"timetuple", datetime_timetuple, METH_NOARGS,
7215
     PyDoc_STR("Return time tuple, compatible with time.localtime().")},
7216
7217
    {"timestamp", datetime_timestamp, METH_NOARGS,
7218
     PyDoc_STR("Return POSIX timestamp as float.")},
7219
7220
    {"utctimetuple", datetime_utctimetuple, METH_NOARGS,
7221
     PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
7222
7223
    DATETIME_DATETIME_ISOFORMAT_METHODDEF
7224
7225
    {"utcoffset", datetime_utcoffset, METH_NOARGS,
7226
     PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
7227
7228
    {"tzname", datetime_tzname,   METH_NOARGS,
7229
     PyDoc_STR("Return self.tzinfo.tzname(self).")},
7230
7231
    {"dst", datetime_dst, METH_NOARGS,
7232
     PyDoc_STR("Return self.tzinfo.dst(self).")},
7233
7234
    DATETIME_DATETIME_REPLACE_METHODDEF
7235
7236
    {"__replace__", _PyCFunction_CAST(datetime_datetime_replace), METH_FASTCALL | METH_KEYWORDS,
7237
     PyDoc_STR("__replace__($self, /, **changes)\n--\n\nThe same as replace().")},
7238
7239
    DATETIME_DATETIME_ASTIMEZONE_METHODDEF
7240
    DATETIME_DATETIME___REDUCE_EX___METHODDEF
7241
    DATETIME_DATETIME___REDUCE___METHODDEF
7242
7243
    {NULL,      NULL}
7244
};
7245
7246
static PyNumberMethods datetime_as_number = {
7247
    datetime_add,                               /* nb_add */
7248
    datetime_subtract,                          /* nb_subtract */
7249
    0,                                          /* nb_multiply */
7250
    0,                                          /* nb_remainder */
7251
    0,                                          /* nb_divmod */
7252
    0,                                          /* nb_power */
7253
    0,                                          /* nb_negative */
7254
    0,                                          /* nb_positive */
7255
    0,                                          /* nb_absolute */
7256
    0,                                          /* nb_bool */
7257
};
7258
7259
static PyTypeObject PyDateTime_DateTimeType = {
7260
    PyVarObject_HEAD_INIT(NULL, 0)
7261
    "datetime.datetime",                        /* tp_name */
7262
    sizeof(PyDateTime_DateTime),                /* tp_basicsize */
7263
    0,                                          /* tp_itemsize */
7264
    datetime_dealloc,                           /* tp_dealloc */
7265
    0,                                          /* tp_vectorcall_offset */
7266
    0,                                          /* tp_getattr */
7267
    0,                                          /* tp_setattr */
7268
    0,                                          /* tp_as_async */
7269
    datetime_repr,                              /* tp_repr */
7270
    &datetime_as_number,                        /* tp_as_number */
7271
    0,                                          /* tp_as_sequence */
7272
    0,                                          /* tp_as_mapping */
7273
    datetime_hash,                              /* tp_hash */
7274
    0,                                          /* tp_call */
7275
    datetime_str,                               /* tp_str */
7276
    PyObject_GenericGetAttr,                    /* tp_getattro */
7277
    0,                                          /* tp_setattro */
7278
    0,                                          /* tp_as_buffer */
7279
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
7280
    datetime_datetime__doc__,                   /* tp_doc */
7281
    0,                                          /* tp_traverse */
7282
    0,                                          /* tp_clear */
7283
    datetime_richcompare,                       /* tp_richcompare */
7284
    0,                                          /* tp_weaklistoffset */
7285
    0,                                          /* tp_iter */
7286
    0,                                          /* tp_iternext */
7287
    datetime_methods,                           /* tp_methods */
7288
    0,                                          /* tp_members */
7289
    datetime_getset,                            /* tp_getset */
7290
    &PyDateTime_DateType,                       /* tp_base */
7291
    0,                                          /* tp_dict */
7292
    0,                                          /* tp_descr_get */
7293
    0,                                          /* tp_descr_set */
7294
    0,                                          /* tp_dictoffset */
7295
    0,                                          /* tp_init */
7296
    datetime_alloc,                             /* tp_alloc */
7297
    datetime_new,                               /* tp_new */
7298
    0,                                          /* tp_free */
7299
};
7300
7301
/* ---------------------------------------------------------------------------
7302
 * datetime C-API.
7303
 */
7304
7305
static PyTypeObject * const capi_types[] = {
7306
    &PyDateTime_DateType,
7307
    &PyDateTime_DateTimeType,
7308
    &PyDateTime_TimeType,
7309
    &PyDateTime_DeltaType,
7310
    &PyDateTime_TZInfoType,
7311
    /* Indirectly, via the utc object. */
7312
    &PyDateTime_TimeZoneType,
7313
};
7314
7315
/* The C-API is process-global.  This violates interpreter isolation
7316
 * due to the objects stored here.  Thus each of those objects must
7317
 * be managed carefully. */
7318
// XXX Can we make this const?
7319
static PyDateTime_CAPI capi = {
7320
    /* The classes must be readied before used here.
7321
     * That will happen the first time the module is loaded.
7322
     * They aren't safe to be shared between interpreters,
7323
     * but that's okay as long as the module is single-phase init. */
7324
    .DateType = &PyDateTime_DateType,
7325
    .DateTimeType = &PyDateTime_DateTimeType,
7326
    .TimeType = &PyDateTime_TimeType,
7327
    .DeltaType = &PyDateTime_DeltaType,
7328
    .TZInfoType = &PyDateTime_TZInfoType,
7329
7330
    .TimeZone_UTC = (PyObject *)&utc_timezone,
7331
7332
    .Date_FromDate = new_date_ex,
7333
    .DateTime_FromDateAndTime = new_datetime_ex,
7334
    .Time_FromTime = new_time_ex,
7335
    .Delta_FromDelta = new_delta_ex,
7336
    .TimeZone_FromTimeZone = new_timezone,
7337
    .DateTime_FromTimestamp = datetime_datetime_fromtimestamp_capi,
7338
    .Date_FromTimestamp = datetime_date_fromtimestamp_capi,
7339
    .DateTime_FromDateAndTimeAndFold = new_datetime_ex2,
7340
    .Time_FromTimeAndFold = new_time_ex2,
7341
};
7342
7343
/* Get a new C API by calling this function.
7344
 * Clients get at C API via PyDateTime_IMPORT, defined in datetime.h.
7345
 */
7346
static inline PyDateTime_CAPI *
7347
get_datetime_capi(void)
7348
12
{
7349
12
    return &capi;
7350
12
}
7351
7352
static PyObject *
7353
create_timezone_from_delta(int days, int sec, int ms, int normalize)
7354
64
{
7355
64
    PyObject *delta = new_delta(days, sec, ms, normalize);
7356
64
    if (delta == NULL) {
7357
0
        return NULL;
7358
0
    }
7359
64
    PyObject *tz = create_timezone(delta, NULL);
7360
64
    Py_DECREF(delta);
7361
64
    return tz;
7362
64
}
7363
7364
7365
/* ---------------------------------------------------------------------------
7366
 * Module state lifecycle.
7367
 */
7368
7369
static int
7370
init_state(datetime_state *st, PyObject *module, PyObject *old_module)
7371
12
{
7372
    /* Each module gets its own heap types. */
7373
12
#define ADD_TYPE(FIELD, SPEC, BASE)                 \
7374
12
    do {                                            \
7375
12
        PyObject *cls = PyType_FromModuleAndSpec(   \
7376
12
                module, SPEC, (PyObject *)BASE);    \
7377
12
        if (cls == NULL) {                          \
7378
0
            return -1;                              \
7379
0
        }                                           \
7380
12
        st->FIELD = (PyTypeObject *)cls;            \
7381
12
    } while (0)
7382
7383
12
    ADD_TYPE(isocalendar_date_type, &isocal_spec, &PyTuple_Type);
7384
12
#undef ADD_TYPE
7385
7386
12
    if (old_module != NULL) {
7387
0
        assert(old_module != module);
7388
0
        datetime_state *st_old = get_module_state(old_module);
7389
0
        *st = (datetime_state){
7390
0
            .isocalendar_date_type = st->isocalendar_date_type,
7391
0
            .us_per_ms = Py_NewRef(st_old->us_per_ms),
7392
0
            .us_per_second = Py_NewRef(st_old->us_per_second),
7393
0
            .us_per_minute = Py_NewRef(st_old->us_per_minute),
7394
0
            .us_per_hour = Py_NewRef(st_old->us_per_hour),
7395
0
            .us_per_day = Py_NewRef(st_old->us_per_day),
7396
0
            .us_per_week = Py_NewRef(st_old->us_per_week),
7397
0
            .seconds_per_day = Py_NewRef(st_old->seconds_per_day),
7398
0
            .epoch = Py_NewRef(st_old->epoch),
7399
0
        };
7400
0
        return 0;
7401
0
    }
7402
7403
12
    st->us_per_ms = PyLong_FromLong(1000);
7404
12
    if (st->us_per_ms == NULL) {
7405
0
        return -1;
7406
0
    }
7407
12
    st->us_per_second = PyLong_FromLong(1000000);
7408
12
    if (st->us_per_second == NULL) {
7409
0
        return -1;
7410
0
    }
7411
12
    st->us_per_minute = PyLong_FromLong(60000000);
7412
12
    if (st->us_per_minute == NULL) {
7413
0
        return -1;
7414
0
    }
7415
12
    st->seconds_per_day = PyLong_FromLong(24 * 3600);
7416
12
    if (st->seconds_per_day == NULL) {
7417
0
        return -1;
7418
0
    }
7419
7420
    /* The rest are too big for 32-bit ints, but even
7421
     * us_per_week fits in 40 bits, so doubles should be exact.
7422
     */
7423
12
    st->us_per_hour = PyLong_FromDouble(3600000000.0);
7424
12
    if (st->us_per_hour == NULL) {
7425
0
        return -1;
7426
0
    }
7427
12
    st->us_per_day = PyLong_FromDouble(86400000000.0);
7428
12
    if (st->us_per_day == NULL) {
7429
0
        return -1;
7430
0
    }
7431
12
    st->us_per_week = PyLong_FromDouble(604800000000.0);
7432
12
    if (st->us_per_week == NULL) {
7433
0
        return -1;
7434
0
    }
7435
7436
    /* Init Unix epoch */
7437
12
    st->epoch = new_datetime(
7438
12
            1970, 1, 1, 0, 0, 0, 0, (PyObject *)&utc_timezone, 0);
7439
12
    if (st->epoch == NULL) {
7440
0
        return -1;
7441
0
    }
7442
7443
12
    return 0;
7444
12
}
7445
7446
static int
7447
traverse_state(datetime_state *st, visitproc visit, void *arg)
7448
797
{
7449
    /* heap types */
7450
797
    Py_VISIT(st->isocalendar_date_type);
7451
7452
797
    return 0;
7453
797
}
7454
7455
static int
7456
clear_state(datetime_state *st)
7457
0
{
7458
0
    Py_CLEAR(st->isocalendar_date_type);
7459
0
    Py_CLEAR(st->us_per_ms);
7460
0
    Py_CLEAR(st->us_per_second);
7461
0
    Py_CLEAR(st->us_per_minute);
7462
0
    Py_CLEAR(st->us_per_hour);
7463
0
    Py_CLEAR(st->us_per_day);
7464
0
    Py_CLEAR(st->us_per_week);
7465
0
    Py_CLEAR(st->seconds_per_day);
7466
0
    Py_CLEAR(st->epoch);
7467
0
    return 0;
7468
0
}
7469
7470
7471
PyStatus
7472
_PyDateTime_InitTypes(PyInterpreterState *interp)
7473
32
{
7474
    /* Bases classes must be initialized before subclasses,
7475
     * so capi_types must have the types in the appropriate order. */
7476
224
    for (size_t i = 0; i < Py_ARRAY_LENGTH(capi_types); i++) {
7477
192
        PyTypeObject *type = capi_types[i];
7478
192
        if (_PyStaticType_InitForExtension(interp, type) < 0) {
7479
0
            return _PyStatus_ERR("could not initialize static types");
7480
0
        }
7481
192
    }
7482
7483
32
#define DATETIME_ADD_MACRO(dict, c, value_expr)         \
7484
448
    do {                                                \
7485
448
        assert(!PyErr_Occurred());                      \
7486
448
        PyObject *value = (value_expr);                 \
7487
448
        if (value == NULL) {                            \
7488
0
            goto error;                                 \
7489
0
        }                                               \
7490
448
        if (PyDict_SetItemString(dict, c, value) < 0) { \
7491
0
            Py_DECREF(value);                           \
7492
0
            goto error;                                 \
7493
0
        }                                               \
7494
448
        Py_DECREF(value);                               \
7495
448
    } while(0)
7496
7497
    /* timedelta values */
7498
32
    PyObject *d = _PyType_GetDict(&PyDateTime_DeltaType);
7499
32
    DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
7500
32
    DATETIME_ADD_MACRO(d, "min", new_delta(-MAX_DELTA_DAYS, 0, 0, 0));
7501
32
    DATETIME_ADD_MACRO(d, "max",
7502
32
                        new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0));
7503
7504
    /* date values */
7505
32
    d = _PyType_GetDict(&PyDateTime_DateType);
7506
32
    DATETIME_ADD_MACRO(d, "min", new_date(1, 1, 1));
7507
32
    DATETIME_ADD_MACRO(d, "max", new_date(MAXYEAR, 12, 31));
7508
32
    DATETIME_ADD_MACRO(d, "resolution", new_delta(1, 0, 0, 0));
7509
7510
    /* time values */
7511
32
    d = _PyType_GetDict(&PyDateTime_TimeType);
7512
32
    DATETIME_ADD_MACRO(d, "min", new_time(0, 0, 0, 0, Py_None, 0));
7513
32
    DATETIME_ADD_MACRO(d, "max", new_time(23, 59, 59, 999999, Py_None, 0));
7514
32
    DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
7515
7516
    /* datetime values */
7517
32
    d = _PyType_GetDict(&PyDateTime_DateTimeType);
7518
32
    DATETIME_ADD_MACRO(d, "min",
7519
32
                        new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0));
7520
32
    DATETIME_ADD_MACRO(d, "max", new_datetime(MAXYEAR, 12, 31, 23, 59, 59,
7521
32
                                                999999, Py_None, 0));
7522
32
    DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
7523
7524
    /* timezone values */
7525
32
    d = _PyType_GetDict(&PyDateTime_TimeZoneType);
7526
32
    if (PyDict_SetItemString(d, "utc", (PyObject *)&utc_timezone) < 0) {
7527
0
        goto error;
7528
0
    }
7529
7530
    /* bpo-37642: These attributes are rounded to the nearest minute for backwards
7531
    * compatibility, even though the constructor will accept a wider range of
7532
    * values. This may change in the future.*/
7533
7534
    /* -23:59 */
7535
32
    DATETIME_ADD_MACRO(d, "min", create_timezone_from_delta(-1, 60, 0, 1));
7536
7537
    /* +23:59 */
7538
32
    DATETIME_ADD_MACRO(
7539
32
            d, "max", create_timezone_from_delta(0, (23 * 60 + 59) * 60, 0, 0));
7540
7541
32
#undef DATETIME_ADD_MACRO
7542
7543
32
    return _PyStatus_OK();
7544
7545
0
error:
7546
0
    return _PyStatus_NO_MEMORY();
7547
32
}
7548
7549
7550
/* ---------------------------------------------------------------------------
7551
 * Module methods and initialization.
7552
 */
7553
7554
static PyMethodDef module_methods[] = {
7555
    {NULL, NULL}
7556
};
7557
7558
7559
static int
7560
_datetime_exec(PyObject *module)
7561
12
{
7562
12
    int rc = -1;
7563
12
    datetime_state *st = get_module_state(module);
7564
7565
12
    PyInterpreterState *interp = PyInterpreterState_Get();
7566
12
    PyObject *old_module = get_current_module(interp);
7567
12
    if (PyErr_Occurred()) {
7568
0
        assert(old_module == NULL);
7569
0
        goto error;
7570
0
    }
7571
    /* We actually set the "current" module right before a successful return. */
7572
7573
84
    for (size_t i = 0; i < Py_ARRAY_LENGTH(capi_types); i++) {
7574
72
        PyTypeObject *type = capi_types[i];
7575
72
        const char *name = _PyType_Name(type);
7576
72
        assert(name != NULL);
7577
72
        if (PyModule_AddObjectRef(module, name, (PyObject *)type) < 0) {
7578
0
            goto error;
7579
0
        }
7580
72
    }
7581
7582
12
    if (init_state(st, module, old_module) < 0) {
7583
0
        goto error;
7584
0
    }
7585
7586
    /* Add module level attributes */
7587
12
    if (PyModule_AddIntMacro(module, MINYEAR) < 0) {
7588
0
        goto error;
7589
0
    }
7590
12
    if (PyModule_AddIntMacro(module, MAXYEAR) < 0) {
7591
0
        goto error;
7592
0
    }
7593
12
    if (PyModule_AddObjectRef(module, "UTC", (PyObject *)&utc_timezone) < 0) {
7594
0
        goto error;
7595
0
    }
7596
7597
    /* At last, set up and add the encapsulated C API */
7598
12
    PyDateTime_CAPI *capi = get_datetime_capi();
7599
12
    if (capi == NULL) {
7600
0
        goto error;
7601
0
    }
7602
12
    PyObject *capsule = PyCapsule_New(capi, PyDateTime_CAPSULE_NAME, NULL);
7603
    // (capsule == NULL) is handled by PyModule_Add
7604
12
    if (PyModule_Add(module, "datetime_CAPI", capsule) < 0) {
7605
0
        goto error;
7606
0
    }
7607
7608
    /* A 4-year cycle has an extra leap day over what we'd get from
7609
     * pasting together 4 single years.
7610
     */
7611
12
    static_assert(DI4Y == 4 * 365 + 1, "DI4Y");
7612
12
    assert(DI4Y == days_before_year(4+1));
7613
7614
    /* Similarly, a 400-year cycle has an extra leap day over what we'd
7615
     * get from pasting together 4 100-year cycles.
7616
     */
7617
12
    static_assert(DI400Y == 4 * DI100Y + 1, "DI400Y");
7618
12
    assert(DI400Y == days_before_year(400+1));
7619
7620
    /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
7621
     * pasting together 25 4-year cycles.
7622
     */
7623
12
    static_assert(DI100Y == 25 * DI4Y - 1, "DI100Y");
7624
12
    assert(DI100Y == days_before_year(100+1));
7625
7626
12
    if (set_current_module(interp, module) < 0) {
7627
0
        goto error;
7628
0
    }
7629
7630
12
    rc = 0;
7631
12
    goto finally;
7632
7633
0
error:
7634
0
    clear_state(st);
7635
7636
12
finally:
7637
12
    Py_XDECREF(old_module);
7638
12
    return rc;
7639
0
}
7640
7641
static PyModuleDef_Slot module_slots[] = {
7642
    _Py_INTERNAL_ABI_SLOT,
7643
    {Py_mod_exec, _datetime_exec},
7644
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
7645
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
7646
    {0, NULL},
7647
};
7648
7649
static int
7650
module_traverse(PyObject *mod, visitproc visit, void *arg)
7651
797
{
7652
797
    datetime_state *st = get_module_state(mod);
7653
797
    traverse_state(st, visit, arg);
7654
797
    return 0;
7655
797
}
7656
7657
static int
7658
module_clear(PyObject *mod)
7659
0
{
7660
0
    datetime_state *st = get_module_state(mod);
7661
0
    clear_state(st);
7662
7663
0
    PyInterpreterState *interp = PyInterpreterState_Get();
7664
0
    clear_current_module(interp, mod);
7665
7666
    // The runtime takes care of the static types for us.
7667
    // See _PyTypes_FiniExtTypes()..
7668
7669
0
    return 0;
7670
0
}
7671
7672
static void
7673
module_free(void *mod)
7674
0
{
7675
0
    (void)module_clear((PyObject *)mod);
7676
0
}
7677
7678
static PyModuleDef datetimemodule = {
7679
    .m_base = PyModuleDef_HEAD_INIT,
7680
    .m_name = "_datetime",
7681
    .m_doc = "Fast implementation of the datetime module.",
7682
    .m_size = sizeof(datetime_state),
7683
    .m_methods = module_methods,
7684
    .m_slots = module_slots,
7685
    .m_traverse = module_traverse,
7686
    .m_clear = module_clear,
7687
    .m_free = module_free,
7688
};
7689
7690
PyMODINIT_FUNC
7691
PyInit__datetime(void)
7692
12
{
7693
12
    return PyModuleDef_Init(&datetimemodule);
7694
12
}
7695
7696
/* ---------------------------------------------------------------------------
7697
Some time zone algebra.  For a datetime x, let
7698
    x.n = x stripped of its timezone -- its naive time.
7699
    x.o = x.utcoffset(), and assuming that doesn't raise an exception or
7700
      return None
7701
    x.d = x.dst(), and assuming that doesn't raise an exception or
7702
      return None
7703
    x.s = x's standard offset, x.o - x.d
7704
7705
Now some derived rules, where k is a duration (timedelta).
7706
7707
1. x.o = x.s + x.d
7708
   This follows from the definition of x.s.
7709
7710
2. If x and y have the same tzinfo member, x.s = y.s.
7711
   This is actually a requirement, an assumption we need to make about
7712
   sane tzinfo classes.
7713
7714
3. The naive UTC time corresponding to x is x.n - x.o.
7715
   This is again a requirement for a sane tzinfo class.
7716
7717
4. (x+k).s = x.s
7718
   This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
7719
7720
5. (x+k).n = x.n + k
7721
   Again follows from how arithmetic is defined.
7722
7723
Now we can explain tz.fromutc(x).  Let's assume it's an interesting case
7724
(meaning that the various tzinfo methods exist, and don't blow up or return
7725
None when called).
7726
7727
The function wants to return a datetime y with timezone tz, equivalent to x.
7728
x is already in UTC.
7729
7730
By #3, we want
7731
7732
    y.n - y.o = x.n                             [1]
7733
7734
The algorithm starts by attaching tz to x.n, and calling that y.  So
7735
x.n = y.n at the start.  Then it wants to add a duration k to y, so that [1]
7736
becomes true; in effect, we want to solve [2] for k:
7737
7738
   (y+k).n - (y+k).o = x.n                      [2]
7739
7740
By #1, this is the same as
7741
7742
   (y+k).n - ((y+k).s + (y+k).d) = x.n          [3]
7743
7744
By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
7745
Substituting that into [3],
7746
7747
   x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
7748
   k - (y+k).s - (y+k).d = 0; rearranging,
7749
   k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
7750
   k = y.s - (y+k).d
7751
7752
On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
7753
approximate k by ignoring the (y+k).d term at first.  Note that k can't be
7754
very large, since all offset-returning methods return a duration of magnitude
7755
less than 24 hours.  For that reason, if y is firmly in std time, (y+k).d must
7756
be 0, so ignoring it has no consequence then.
7757
7758
In any case, the new value is
7759
7760
    z = y + y.s                                 [4]
7761
7762
It's helpful to step back at look at [4] from a higher level:  it's simply
7763
mapping from UTC to tz's standard time.
7764
7765
At this point, if
7766
7767
    z.n - z.o = x.n                             [5]
7768
7769
we have an equivalent time, and are almost done.  The insecurity here is
7770
at the start of daylight time.  Picture US Eastern for concreteness.  The wall
7771
time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
7772
sense then.  The docs ask that an Eastern tzinfo class consider such a time to
7773
be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
7774
on the day DST starts.  We want to return the 1:MM EST spelling because that's
7775
the only spelling that makes sense on the local wall clock.
7776
7777
In fact, if [5] holds at this point, we do have the standard-time spelling,
7778
but that takes a bit of proof.  We first prove a stronger result.  What's the
7779
difference between the LHS and RHS of [5]?  Let
7780
7781
    diff = x.n - (z.n - z.o)                    [6]
7782
7783
Now
7784
    z.n =                       by [4]
7785
    (y + y.s).n =               by #5
7786
    y.n + y.s =                 since y.n = x.n
7787
    x.n + y.s =                 since z and y are have the same tzinfo member,
7788
                                    y.s = z.s by #2
7789
    x.n + z.s
7790
7791
Plugging that back into [6] gives
7792
7793
    diff =
7794
    x.n - ((x.n + z.s) - z.o) =     expanding
7795
    x.n - x.n - z.s + z.o =         cancelling
7796
    - z.s + z.o =                   by #2
7797
    z.d
7798
7799
So diff = z.d.
7800
7801
If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
7802
spelling we wanted in the endcase described above.  We're done.  Contrarily,
7803
if z.d = 0, then we have a UTC equivalent, and are also done.
7804
7805
If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
7806
add to z (in effect, z is in tz's standard time, and we need to shift the
7807
local clock into tz's daylight time).
7808
7809
Let
7810
7811
    z' = z + z.d = z + diff                     [7]
7812
7813
and we can again ask whether
7814
7815
    z'.n - z'.o = x.n                           [8]
7816
7817
If so, we're done.  If not, the tzinfo class is insane, according to the
7818
assumptions we've made.  This also requires a bit of proof.  As before, let's
7819
compute the difference between the LHS and RHS of [8] (and skipping some of
7820
the justifications for the kinds of substitutions we've done several times
7821
already):
7822
7823
    diff' = x.n - (z'.n - z'.o) =           replacing z'.n via [7]
7824
        x.n  - (z.n + diff - z'.o) =    replacing diff via [6]
7825
        x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
7826
        x.n - z.n - x.n + z.n - z.o + z'.o =    cancel x.n
7827
        - z.n + z.n - z.o + z'.o =              cancel z.n
7828
        - z.o + z'.o =                      #1 twice
7829
        -z.s - z.d + z'.s + z'.d =          z and z' have same tzinfo
7830
        z'.d - z.d
7831
7832
So z' is UTC-equivalent to x iff z'.d = z.d at this point.  If they are equal,
7833
we've found the UTC-equivalent so are done.  In fact, we stop with [7] and
7834
return z', not bothering to compute z'.d.
7835
7836
How could z.d and z'd differ?  z' = z + z.d [7], so merely moving z' by
7837
a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
7838
would have to change the result dst() returns:  we start in DST, and moving
7839
a little further into it takes us out of DST.
7840
7841
There isn't a sane case where this can happen.  The closest it gets is at
7842
the end of DST, where there's an hour in UTC with no spelling in a hybrid
7843
tzinfo class.  In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT.  During
7844
that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
7845
UTC) because the docs insist on that, but 0:MM is taken as being in daylight
7846
time (4:MM UTC).  There is no local time mapping to 5:MM UTC.  The local
7847
clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
7848
standard time.  Since that's what the local clock *does*, we want to map both
7849
UTC hours 5:MM and 6:MM to 1:MM Eastern.  The result is ambiguous
7850
in local time, but so it goes -- it's the way the local clock works.
7851
7852
When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
7853
so z=0:MM.  z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
7854
z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
7855
(correctly) concludes that z' is not UTC-equivalent to x.
7856
7857
Because we know z.d said z was in daylight time (else [5] would have held and
7858
we would have stopped then), and we know z.d != z'.d (else [8] would have held
7859
and we would have stopped then), and there are only 2 possible values dst() can
7860
return in Eastern, it follows that z'.d must be 0 (which it is in the example,
7861
but the reasoning doesn't depend on the example -- it depends on there being
7862
two possible dst() outcomes, one zero and the other non-zero).  Therefore
7863
z' must be in standard time, and is the spelling we want in this case.
7864
7865
Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
7866
concerned (because it takes z' as being in standard time rather than the
7867
daylight time we intend here), but returning it gives the real-life "local
7868
clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
7869
tz.
7870
7871
When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
7872
the 1:MM standard time spelling we want.
7873
7874
So how can this break?  One of the assumptions must be violated.  Two
7875
possibilities:
7876
7877
1) [2] effectively says that y.s is invariant across all y belong to a given
7878
   time zone.  This isn't true if, for political reasons or continental drift,
7879
   a region decides to change its base offset from UTC.
7880
7881
2) There may be versions of "double daylight" time where the tail end of
7882
   the analysis gives up a step too early.  I haven't thought about that
7883
   enough to say.
7884
7885
In any case, it's clear that the default fromutc() is strong enough to handle
7886
"almost all" time zones:  so long as the standard offset is invariant, it
7887
doesn't matter if daylight time transition points change from year to year, or
7888
if daylight time is skipped in some years; it doesn't matter how large or
7889
small dst() may get within its bounds; and it doesn't even matter if some
7890
perverse time zone returns a negative dst()).  So a breaking case must be
7891
pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
7892
--------------------------------------------------------------------------- */