Coverage Report

Created: 2026-10-17 06:15

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