Coverage Report

Created: 2025-08-26 06:26

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