Coverage Report

Created: 2026-03-23 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Python/pytime.c
Line
Count
Source
1
#include "Python.h"
2
#include "pycore_initconfig.h"    // _PyStatus_ERR
3
#include "pycore_pystate.h"       // _Py_AssertHoldsTstate()
4
#include "pycore_runtime.h"       // _PyRuntime
5
#include "pycore_time.h"          // export _PyLong_FromTime_t()
6
7
#include <time.h>                 // gmtime_r()
8
#ifdef HAVE_SYS_TIME_H
9
#  include <sys/time.h>           // gettimeofday()
10
#endif
11
#ifdef MS_WINDOWS
12
#  include <winsock2.h>           // struct timeval
13
#endif
14
15
#if defined(__APPLE__)
16
#  include <mach/mach_time.h>     // mach_absolute_time(), mach_timebase_info()
17
18
#if defined(__APPLE__) && defined(__has_builtin)
19
#  if __has_builtin(__builtin_available)
20
#    define HAVE_CLOCK_GETTIME_RUNTIME __builtin_available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
21
#  endif
22
#endif
23
#endif
24
25
/* To millisecond (10^-3) */
26
562k
#define SEC_TO_MS 1000
27
28
/* To microseconds (10^-6) */
29
562k
#define MS_TO_US 1000
30
0
#define SEC_TO_US (SEC_TO_MS * MS_TO_US)
31
32
/* To nanoseconds (10^-9) */
33
1.13M
#define US_TO_NS 1000
34
562k
#define MS_TO_NS (MS_TO_US * US_TO_NS)
35
562k
#define SEC_TO_NS (SEC_TO_MS * MS_TO_NS)
36
37
/* Conversion from nanoseconds */
38
0
#define NS_TO_MS (1000 * 1000)
39
0
#define NS_TO_US (1000)
40
#define NS_TO_100NS (100)
41
42
#if SIZEOF_TIME_T == SIZEOF_LONG_LONG
43
#  define PY_TIME_T_MAX LLONG_MAX
44
0
#  define PY_TIME_T_MIN LLONG_MIN
45
#elif SIZEOF_TIME_T == SIZEOF_LONG
46
#  define PY_TIME_T_MAX LONG_MAX
47
#  define PY_TIME_T_MIN LONG_MIN
48
#else
49
#  error "unsupported time_t size"
50
#endif
51
52
#if PY_TIME_T_MAX + PY_TIME_T_MIN != -1
53
#  error "time_t is not a two's complement integer type"
54
#endif
55
56
#if PyTime_MIN + PyTime_MAX != -1
57
#  error "PyTime_t is not a two's complement integer type"
58
#endif
59
60
61
static PyTime_t
62
_PyTime_GCD(PyTime_t x, PyTime_t y)
63
72
{
64
    // Euclidean algorithm
65
72
    assert(x >= 1);
66
72
    assert(y >= 1);
67
144
    while (y != 0) {
68
72
        PyTime_t tmp = y;
69
72
        y = x % y;
70
72
        x = tmp;
71
72
    }
72
72
    assert(x >= 1);
73
72
    return x;
74
72
}
75
76
77
int
78
_PyTimeFraction_Set(_PyTimeFraction *frac, PyTime_t numer, PyTime_t denom)
79
72
{
80
72
    if (numer < 1 || denom < 1) {
81
0
        return -1;
82
0
    }
83
84
72
    PyTime_t gcd = _PyTime_GCD(numer, denom);
85
72
    frac->numer = numer / gcd;
86
72
    frac->denom = denom / gcd;
87
72
    return 0;
88
72
}
89
90
91
double
92
_PyTimeFraction_Resolution(const _PyTimeFraction *frac)
93
0
{
94
0
    return (double)frac->numer / (double)frac->denom / 1e9;
95
0
}
96
97
98
static void
99
pytime_time_t_overflow(void)
100
0
{
101
0
    PyErr_SetString(PyExc_OverflowError,
102
0
                    "timestamp out of range for platform time_t");
103
0
}
104
105
106
static void
107
pytime_overflow(void)
108
0
{
109
0
    PyErr_SetString(PyExc_OverflowError,
110
0
                    "timestamp too large to convert to C PyTime_t");
111
0
}
112
113
114
// Compute t1 + t2. Clamp to [PyTime_MIN; PyTime_MAX] on overflow.
115
static inline int
116
pytime_add(PyTime_t *t1, PyTime_t t2)
117
196k
{
118
196k
    if (t2 > 0 && *t1 > PyTime_MAX - t2) {
119
0
        *t1 = PyTime_MAX;
120
0
        return -1;
121
0
    }
122
196k
    else if (t2 < 0 && *t1 < PyTime_MIN - t2) {
123
0
        *t1 = PyTime_MIN;
124
0
        return -1;
125
0
    }
126
196k
    else {
127
196k
        *t1 += t2;
128
196k
        return 0;
129
196k
    }
130
196k
}
131
132
133
PyTime_t
134
_PyTime_Add(PyTime_t t1, PyTime_t t2)
135
0
{
136
0
    (void)pytime_add(&t1, t2);
137
0
    return t1;
138
0
}
139
140
141
static inline int
142
pytime_mul_check_overflow(PyTime_t a, PyTime_t b)
143
773k
{
144
773k
    if (b != 0) {
145
773k
        assert(b > 0);
146
773k
        return ((a < PyTime_MIN / b) || (PyTime_MAX / b < a));
147
773k
    }
148
0
    else {
149
0
        return 0;
150
0
    }
151
773k
}
152
153
154
// Compute t * k. Clamp to [PyTime_MIN; PyTime_MAX] on overflow.
155
static inline int
156
pytime_mul(PyTime_t *t, PyTime_t k)
157
773k
{
158
773k
    assert(k >= 0);
159
773k
    if (pytime_mul_check_overflow(*t, k)) {
160
0
        *t = (*t >= 0) ? PyTime_MAX : PyTime_MIN;
161
0
        return -1;
162
0
    }
163
773k
    else {
164
773k
        *t *= k;
165
773k
        return 0;
166
773k
    }
167
773k
}
168
169
170
// Compute t * k. Clamp to [PyTime_MIN; PyTime_MAX] on overflow.
171
static inline PyTime_t
172
_PyTime_Mul(PyTime_t t, PyTime_t k)
173
576k
{
174
576k
    (void)pytime_mul(&t, k);
175
576k
    return t;
176
576k
}
177
178
179
PyTime_t
180
_PyTimeFraction_Mul(PyTime_t ticks, const _PyTimeFraction *frac)
181
0
{
182
0
    const PyTime_t mul = frac->numer;
183
0
    const PyTime_t div = frac->denom;
184
185
0
    if (div == 1) {
186
        // Fast-path taken by mach_absolute_time() with 1/1 time base.
187
0
        return _PyTime_Mul(ticks, mul);
188
0
    }
189
190
    /* Compute (ticks * mul / div) in two parts to reduce the risk of integer
191
       overflow: compute the integer part, and then the remaining part.
192
193
       (ticks * mul) / div == (ticks / div) * mul + (ticks % div) * mul / div
194
    */
195
0
    PyTime_t intpart, remaining;
196
0
    intpart = ticks / div;
197
0
    ticks %= div;
198
0
    remaining = _PyTime_Mul(ticks, mul) / div;
199
    // intpart * mul + remaining
200
0
    return _PyTime_Add(_PyTime_Mul(intpart, mul), remaining);
201
0
}
202
203
204
time_t
205
_PyLong_AsTime_t(PyObject *obj)
206
0
{
207
0
#if SIZEOF_TIME_T == SIZEOF_LONG_LONG
208
0
    long long val = PyLong_AsLongLong(obj);
209
#elif SIZEOF_TIME_T <= SIZEOF_LONG
210
    long val = PyLong_AsLong(obj);
211
#else
212
#   error "unsupported time_t size"
213
#endif
214
0
    if (val == -1 && PyErr_Occurred()) {
215
0
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
216
0
            pytime_time_t_overflow();
217
0
        }
218
0
        return -1;
219
0
    }
220
0
    return (time_t)val;
221
0
}
222
223
224
PyObject *
225
_PyLong_FromTime_t(time_t t)
226
1.06M
{
227
1.06M
#if SIZEOF_TIME_T == SIZEOF_LONG_LONG
228
1.06M
    return PyLong_FromLongLong((long long)t);
229
#elif SIZEOF_TIME_T <= SIZEOF_LONG
230
    return PyLong_FromLong((long)t);
231
#else
232
#   error "unsupported time_t size"
233
#endif
234
1.06M
}
235
236
237
// Convert PyTime_t to time_t.
238
// Return 0 on success. Return -1 and clamp the value on overflow.
239
static int
240
_PyTime_AsTime_t(PyTime_t t, time_t *t2)
241
0
{
242
#if SIZEOF_TIME_T < _SIZEOF_PYTIME_T
243
    if ((PyTime_t)PY_TIME_T_MAX < t) {
244
        *t2 = PY_TIME_T_MAX;
245
        return -1;
246
    }
247
    if (t < (PyTime_t)PY_TIME_T_MIN) {
248
        *t2 = PY_TIME_T_MIN;
249
        return -1;
250
    }
251
#endif
252
0
    *t2 = (time_t)t;
253
0
    return 0;
254
0
}
255
256
257
#ifdef MS_WINDOWS
258
// Convert PyTime_t to long.
259
// Return 0 on success. Return -1 and clamp the value on overflow.
260
static int
261
_PyTime_AsCLong(PyTime_t t, long *t2)
262
{
263
#if SIZEOF_LONG < _SIZEOF_PYTIME_T
264
    if ((PyTime_t)LONG_MAX < t) {
265
        *t2 = LONG_MAX;
266
        return -1;
267
    }
268
    if (t < (PyTime_t)LONG_MIN) {
269
        *t2 = LONG_MIN;
270
        return -1;
271
    }
272
#endif
273
    *t2 = (long)t;
274
    return 0;
275
}
276
277
// Seconds between 1601-01-01 and 1970-01-01:
278
// 369 years + 89 leap days.
279
#define SECS_BETWEEN_EPOCHS 11644473600LL
280
#define HUNDRED_NS_PER_SEC 10000000LL
281
282
// Calculate day of year (0-365) from SYSTEMTIME
283
static int
284
_PyTime_calc_yday(const SYSTEMTIME *st)
285
{
286
    // Cumulative days before each month (non-leap year)
287
    static const int days_before_month[] = {
288
        0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
289
    };
290
    int yday = days_before_month[st->wMonth - 1] + st->wDay - 1;
291
    // Account for leap day if we're past February in a leap year.
292
    if (st->wMonth > 2) {
293
        // Leap year rules (Gregorian calendar):
294
        // - Years divisible by 4 are leap years
295
        // - EXCEPT years divisible by 100 are NOT leap years
296
        // - EXCEPT years divisible by 400 ARE leap years
297
        int year = st->wYear;
298
        int is_leap = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
299
        yday += is_leap;
300
    }
301
    return yday;
302
}
303
304
// Convert time_t to struct tm using Windows FILETIME API.
305
// If is_local is true, convert to local time.
306
// Fallback for negative timestamps that localtime_s/gmtime_s cannot handle.
307
// Return 0 on success. Return -1 on error.
308
static int
309
_PyTime_windows_filetime(time_t timer, struct tm *tm, int is_local)
310
{
311
    /* Check for underflow - FILETIME epoch is 1601-01-01 */
312
    if (timer < -SECS_BETWEEN_EPOCHS) {
313
        PyErr_SetString(PyExc_OverflowError, "timestamp out of range for Windows FILETIME");
314
        return -1;
315
    }
316
317
    /* Convert time_t to FILETIME (100-nanosecond intervals since 1601-01-01) */
318
    ULONGLONG ticks = ((ULONGLONG)timer + SECS_BETWEEN_EPOCHS) * HUNDRED_NS_PER_SEC;
319
    FILETIME ft;
320
    ft.dwLowDateTime = (DWORD)(ticks); // cast to DWORD truncates to low 32 bits
321
    ft.dwHighDateTime = (DWORD)(ticks >> 32);
322
323
    /* Convert FILETIME to SYSTEMTIME (UTC) */
324
    SYSTEMTIME st_utc;
325
    if (!FileTimeToSystemTime(&ft, &st_utc)) {
326
        PyErr_SetFromWindowsErr(0);
327
        return -1;
328
    }
329
330
    SYSTEMTIME st_result;
331
    if (is_local) {
332
        /* Convert UTC SYSTEMTIME to local SYSTEMTIME.
333
         * We use SystemTimeToTzSpecificLocalTime instead of
334
         * FileTimeToLocalFileTime because the latter always applies the
335
         * _current_ DST bias, whereas the former applies the correct
336
         * DST rules for the date being converted (gh-80620). */
337
        if (!SystemTimeToTzSpecificLocalTime(NULL, &st_utc, &st_result)) {
338
            PyErr_SetFromWindowsErr(0);
339
            return -1;
340
        }
341
    }
342
    else {
343
        st_result = st_utc;
344
    }
345
346
    /* Convert SYSTEMTIME to struct tm */
347
    tm->tm_year = st_result.wYear - 1900;
348
    tm->tm_mon = st_result.wMonth - 1; /* SYSTEMTIME: 1-12, tm: 0-11 */
349
    tm->tm_mday = st_result.wDay;
350
    tm->tm_hour = st_result.wHour;
351
    tm->tm_min = st_result.wMinute;
352
    tm->tm_sec = st_result.wSecond;
353
    tm->tm_wday = st_result.wDayOfWeek; /* 0=Sunday */
354
355
    // `time.gmtime` and `time.localtime` will return `struct_time` containing this
356
    tm->tm_yday = _PyTime_calc_yday(&st_result);
357
358
    /* DST flag: -1 (unknown) for local time on historical dates, 0 for UTC */
359
    tm->tm_isdst = is_local ? -1 : 0;
360
361
    return 0;
362
}
363
#endif
364
365
366
/* Round to nearest with ties going to nearest even integer
367
   (_PyTime_ROUND_HALF_EVEN) */
368
static double
369
pytime_round_half_even(double x)
370
0
{
371
0
    double rounded = round(x);
372
0
    if (fabs(x-rounded) == 0.5) {
373
        /* halfway case: round to even */
374
0
        rounded = 2.0 * round(x / 2.0);
375
0
    }
376
0
    return rounded;
377
0
}
378
379
380
static double
381
pytime_round(double x, _PyTime_round_t round)
382
0
{
383
    /* volatile avoids optimization changing how numbers are rounded */
384
0
    volatile double d;
385
386
0
    d = x;
387
0
    if (round == _PyTime_ROUND_HALF_EVEN) {
388
0
        d = pytime_round_half_even(d);
389
0
    }
390
0
    else if (round == _PyTime_ROUND_CEILING) {
391
0
        d = ceil(d);
392
0
    }
393
0
    else if (round == _PyTime_ROUND_FLOOR) {
394
0
        d = floor(d);
395
0
    }
396
0
    else {
397
0
        assert(round == _PyTime_ROUND_UP);
398
0
        d = (d >= 0.0) ? ceil(d) : floor(d);
399
0
    }
400
0
    return d;
401
0
}
402
403
404
static int
405
pytime_double_to_denominator(double d, time_t *sec, long *numerator,
406
                             long idenominator, _PyTime_round_t round)
407
0
{
408
0
    double denominator = (double)idenominator;
409
0
    double intpart;
410
    /* volatile avoids optimization changing how numbers are rounded */
411
0
    volatile double floatpart;
412
413
0
    floatpart = modf(d, &intpart);
414
415
0
    floatpart *= denominator;
416
0
    floatpart = pytime_round(floatpart, round);
417
0
    if (floatpart >= denominator) {
418
0
        floatpart -= denominator;
419
0
        intpart += 1.0;
420
0
    }
421
0
    else if (floatpart < 0) {
422
0
        floatpart += denominator;
423
0
        intpart -= 1.0;
424
0
    }
425
0
    assert(0.0 <= floatpart && floatpart < denominator);
426
427
    /*
428
       Conversion of an out-of-range value to time_t gives undefined behaviour
429
       (C99 §6.3.1.4p1), so we must guard against it. However, checking that
430
       `intpart` is in range is delicate: the obvious expression `intpart <=
431
       PY_TIME_T_MAX` will first convert the value `PY_TIME_T_MAX` to a double,
432
       potentially changing its value and leading to us failing to catch some
433
       UB-inducing values. The code below works correctly under the mild
434
       assumption that time_t is a two's complement integer type with no trap
435
       representation, and that `PY_TIME_T_MIN` is within the representable
436
       range of a C double.
437
438
       Note: we want the `if` condition below to be true for NaNs; therefore,
439
       resist any temptation to simplify by applying De Morgan's laws.
440
    */
441
0
    if (!((double)PY_TIME_T_MIN <= intpart && intpart < -(double)PY_TIME_T_MIN)) {
442
0
        pytime_time_t_overflow();
443
0
        return -1;
444
0
    }
445
0
    *sec = (time_t)intpart;
446
0
    *numerator = (long)floatpart;
447
0
    assert(0 <= *numerator && *numerator < idenominator);
448
0
    return 0;
449
0
}
450
451
452
static int
453
pytime_object_to_denominator(PyObject *obj, time_t *sec, long *numerator,
454
                             long denominator, _PyTime_round_t round)
455
0
{
456
0
    assert(denominator >= 1);
457
458
0
    if (PyIndex_Check(obj)) {
459
0
        *sec = _PyLong_AsTime_t(obj);
460
0
        *numerator = 0;
461
0
        if (*sec == (time_t)-1 && PyErr_Occurred()) {
462
0
            return -1;
463
0
        }
464
0
        return 0;
465
0
    }
466
0
    else {
467
0
        double d = PyFloat_AsDouble(obj);
468
0
        if (d == -1 && PyErr_Occurred()) {
469
0
            *numerator = 0;
470
0
            return -1;
471
0
        }
472
0
        if (isnan(d)) {
473
0
            *numerator = 0;
474
0
            PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
475
0
            return -1;
476
0
        }
477
0
        return pytime_double_to_denominator(d, sec, numerator,
478
0
                                            denominator, round);
479
0
    }
480
0
}
481
482
483
int
484
_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
485
0
{
486
0
    if (PyIndex_Check(obj)) {
487
0
        *sec = _PyLong_AsTime_t(obj);
488
0
        if (*sec == (time_t)-1 && PyErr_Occurred()) {
489
0
            return -1;
490
0
        }
491
0
        return 0;
492
0
    }
493
0
    else {
494
0
        double intpart;
495
        /* volatile avoids optimization changing how numbers are rounded */
496
0
        volatile double d;
497
498
0
        d = PyFloat_AsDouble(obj);
499
0
        if (d == -1 && PyErr_Occurred()) {
500
0
            return -1;
501
0
        }
502
0
        if (isnan(d)) {
503
0
            PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
504
0
            return -1;
505
0
        }
506
507
0
        d = pytime_round(d, round);
508
0
        (void)modf(d, &intpart);
509
510
        /* See comments in pytime_double_to_denominator */
511
0
        if (!((double)PY_TIME_T_MIN <= intpart && intpart < -(double)PY_TIME_T_MIN)) {
512
0
            pytime_time_t_overflow();
513
0
            return -1;
514
0
        }
515
0
        *sec = (time_t)intpart;
516
0
        return 0;
517
0
    }
518
0
}
519
520
521
int
522
_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
523
                         _PyTime_round_t round)
524
0
{
525
0
    return pytime_object_to_denominator(obj, sec, nsec, SEC_TO_NS, round);
526
0
}
527
528
529
int
530
_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
531
                        _PyTime_round_t round)
532
0
{
533
0
    return pytime_object_to_denominator(obj, sec, usec, SEC_TO_US, round);
534
0
}
535
536
537
PyTime_t
538
_PyTime_FromSeconds(int seconds)
539
250k
{
540
    /* ensure that integer overflow cannot happen, int type should have 32
541
       bits, whereas PyTime_t type has at least 64 bits (SEC_TO_NS takes 30
542
       bits). */
543
250k
    static_assert(INT_MAX <= PyTime_MAX / SEC_TO_NS, "PyTime_t overflow");
544
250k
    static_assert(INT_MIN >= PyTime_MIN / SEC_TO_NS, "PyTime_t underflow");
545
546
250k
    PyTime_t t = (PyTime_t)seconds;
547
250k
    assert((t >= 0 && t <= PyTime_MAX / SEC_TO_NS)
548
250k
           || (t < 0 && t >= PyTime_MIN / SEC_TO_NS));
549
250k
    t *= SEC_TO_NS;
550
250k
    return t;
551
250k
}
552
553
554
PyTime_t
555
_PyTime_FromMicrosecondsClamp(PyTime_t us)
556
576k
{
557
576k
    PyTime_t ns = _PyTime_Mul(us, US_TO_NS);
558
576k
    return ns;
559
576k
}
560
561
562
#ifdef HAVE_CLOCK_GETTIME
563
static int
564
pytime_fromtimespec(PyTime_t *tp, const struct timespec *ts, int raise_exc)
565
196k
{
566
196k
    PyTime_t t, tv_nsec;
567
568
196k
    static_assert(sizeof(ts->tv_sec) <= sizeof(PyTime_t),
569
196k
                  "timespec.tv_sec is larger than PyTime_t");
570
196k
    t = (PyTime_t)ts->tv_sec;
571
572
196k
    int res1 = pytime_mul(&t, SEC_TO_NS);
573
574
196k
    tv_nsec = ts->tv_nsec;
575
196k
    int res2 = pytime_add(&t, tv_nsec);
576
577
196k
    *tp = t;
578
579
196k
    if (raise_exc && (res1 < 0 || res2 < 0)) {
580
0
        pytime_overflow();
581
0
        return -1;
582
0
    }
583
196k
    return 0;
584
196k
}
585
586
int
587
_PyTime_FromTimespec(PyTime_t *tp, const struct timespec *ts)
588
0
{
589
0
    return pytime_fromtimespec(tp, ts, 1);
590
0
}
591
#endif
592
593
594
#ifndef MS_WINDOWS
595
static int
596
pytime_fromtimeval(PyTime_t *tp, struct timeval *tv, int raise_exc)
597
0
{
598
0
    static_assert(sizeof(tv->tv_sec) <= sizeof(PyTime_t),
599
0
                  "timeval.tv_sec is larger than PyTime_t");
600
0
    PyTime_t t = (PyTime_t)tv->tv_sec;
601
602
0
    int res1 = pytime_mul(&t, SEC_TO_NS);
603
604
0
    PyTime_t usec = (PyTime_t)tv->tv_usec * US_TO_NS;
605
0
    int res2 = pytime_add(&t, usec);
606
607
0
    *tp = t;
608
609
0
    if (raise_exc && (res1 < 0 || res2 < 0)) {
610
0
        pytime_overflow();
611
0
        return -1;
612
0
    }
613
0
    return 0;
614
0
}
615
616
617
int
618
_PyTime_FromTimeval(PyTime_t *tp, struct timeval *tv)
619
0
{
620
0
    return pytime_fromtimeval(tp, tv, 1);
621
0
}
622
#endif
623
624
625
static int
626
pytime_from_double(PyTime_t *tp, double value, _PyTime_round_t round,
627
                   long unit_to_ns)
628
0
{
629
    /* volatile avoids optimization changing how numbers are rounded */
630
0
    volatile double d;
631
632
    /* convert to a number of nanoseconds */
633
0
    d = value;
634
0
    d *= (double)unit_to_ns;
635
0
    d = pytime_round(d, round);
636
637
    /* See comments in pytime_double_to_denominator */
638
0
    if (!((double)PyTime_MIN <= d && d < -(double)PyTime_MIN)) {
639
0
        pytime_time_t_overflow();
640
0
        *tp = 0;
641
0
        return -1;
642
0
    }
643
0
    PyTime_t ns = (PyTime_t)d;
644
645
0
    *tp = ns;
646
0
    return 0;
647
0
}
648
649
650
static int
651
pytime_from_object(PyTime_t *tp, PyObject *obj, _PyTime_round_t round,
652
                   long unit_to_ns)
653
0
{
654
0
    if (PyIndex_Check(obj)) {
655
0
        long long sec = PyLong_AsLongLong(obj);
656
0
        if (sec == -1 && PyErr_Occurred()) {
657
0
            if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
658
0
                pytime_overflow();
659
0
            }
660
0
            return -1;
661
0
        }
662
663
0
        static_assert(sizeof(long long) <= sizeof(PyTime_t),
664
0
                    "PyTime_t is smaller than long long");
665
0
        PyTime_t ns = (PyTime_t)sec;
666
0
        if (pytime_mul(&ns, unit_to_ns) < 0) {
667
0
            pytime_overflow();
668
0
            return -1;
669
0
        }
670
671
0
        *tp = ns;
672
0
        return 0;
673
0
    }
674
0
    else {
675
0
        double d;
676
0
        d = PyFloat_AsDouble(obj);
677
0
        if (d == -1 && PyErr_Occurred()) {
678
0
            return -1;
679
0
        }
680
0
        if (isnan(d)) {
681
0
            PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
682
0
            return -1;
683
0
        }
684
0
        return pytime_from_double(tp, d, round, unit_to_ns);
685
0
    }
686
0
}
687
688
689
int
690
_PyTime_FromSecondsObject(PyTime_t *tp, PyObject *obj, _PyTime_round_t round)
691
0
{
692
0
    return pytime_from_object(tp, obj, round, SEC_TO_NS);
693
0
}
694
695
696
int
697
_PyTime_FromMillisecondsObject(PyTime_t *tp, PyObject *obj, _PyTime_round_t round)
698
0
{
699
0
    return pytime_from_object(tp, obj, round, MS_TO_NS);
700
0
}
701
702
703
double
704
PyTime_AsSecondsDouble(PyTime_t ns)
705
115k
{
706
    /* volatile avoids optimization changing how numbers are rounded */
707
115k
    volatile double d;
708
709
115k
    if (ns % SEC_TO_NS == 0) {
710
        /* Divide using integers to avoid rounding issues on the integer part.
711
           1e-9 cannot be stored exactly in IEEE 64-bit. */
712
0
        PyTime_t secs = ns / SEC_TO_NS;
713
0
        d = (double)secs;
714
0
    }
715
115k
    else {
716
115k
        d = (double)ns;
717
115k
        d /= 1e9;
718
115k
    }
719
115k
    return d;
720
115k
}
721
722
723
int
724
_PyTime_FromSecondsDouble(double seconds, _PyTime_round_t round, PyTime_t *result)
725
0
{
726
0
    return pytime_from_double(result, seconds, round, SEC_TO_NS);
727
0
}
728
729
730
static PyTime_t
731
pytime_divide_round_up(const PyTime_t t, const PyTime_t k)
732
0
{
733
0
    assert(k > 1);
734
0
    if (t >= 0) {
735
        // Don't use (t + k - 1) / k to avoid integer overflow
736
        // if t is equal to PyTime_MAX
737
0
        PyTime_t q = t / k;
738
0
        if (t % k) {
739
0
            q += 1;
740
0
        }
741
0
        return q;
742
0
    }
743
0
    else {
744
        // Don't use (t - (k - 1)) / k to avoid integer overflow
745
        // if t is equals to PyTime_MIN.
746
0
        PyTime_t q = t / k;
747
0
        if (t % k) {
748
0
            q -= 1;
749
0
        }
750
0
        return q;
751
0
    }
752
0
}
753
754
755
static PyTime_t
756
pytime_divide(const PyTime_t t, const PyTime_t k,
757
              const _PyTime_round_t round)
758
0
{
759
0
    assert(k > 1);
760
0
    if (round == _PyTime_ROUND_HALF_EVEN) {
761
0
        PyTime_t x = t / k;
762
0
        PyTime_t r = t % k;
763
0
        PyTime_t abs_r = Py_ABS(r);
764
0
        if (abs_r > k / 2 || (abs_r == k / 2 && (Py_ABS(x) & 1))) {
765
0
            if (t >= 0) {
766
0
                x++;
767
0
            }
768
0
            else {
769
0
                x--;
770
0
            }
771
0
        }
772
0
        return x;
773
0
    }
774
0
    else if (round == _PyTime_ROUND_CEILING) {
775
0
        if (t >= 0) {
776
0
            return pytime_divide_round_up(t, k);
777
0
        }
778
0
        else {
779
0
            return t / k;
780
0
        }
781
0
    }
782
0
    else if (round == _PyTime_ROUND_FLOOR){
783
0
        if (t >= 0) {
784
0
            return t / k;
785
0
        }
786
0
        else {
787
0
            return pytime_divide_round_up(t, k);
788
0
        }
789
0
    }
790
0
    else {
791
0
        assert(round == _PyTime_ROUND_UP);
792
0
        return pytime_divide_round_up(t, k);
793
0
    }
794
0
}
795
796
797
// Compute (t / k, t % k) in (pq, pr).
798
// Make sure that 0 <= pr < k.
799
// Return 0 on success.
800
// Return -1 on underflow and store (PyTime_MIN, 0) in (pq, pr).
801
static int
802
pytime_divmod(const PyTime_t t, const PyTime_t k,
803
              PyTime_t *pq, PyTime_t *pr)
804
0
{
805
0
    assert(k > 1);
806
0
    PyTime_t q = t / k;
807
0
    PyTime_t r = t % k;
808
0
    if (r < 0) {
809
0
        if (q == PyTime_MIN) {
810
0
            *pq = PyTime_MIN;
811
0
            *pr = 0;
812
0
            return -1;
813
0
        }
814
0
        r += k;
815
0
        q -= 1;
816
0
    }
817
0
    assert(0 <= r && r < k);
818
819
0
    *pq = q;
820
0
    *pr = r;
821
0
    return 0;
822
0
}
823
824
825
#ifdef MS_WINDOWS
826
PyTime_t
827
_PyTime_As100Nanoseconds(PyTime_t ns, _PyTime_round_t round)
828
{
829
    return pytime_divide(ns, NS_TO_100NS, round);
830
}
831
#endif
832
833
834
PyTime_t
835
_PyTime_AsMicroseconds(PyTime_t ns, _PyTime_round_t round)
836
0
{
837
0
    return pytime_divide(ns, NS_TO_US, round);
838
0
}
839
840
841
PyTime_t
842
_PyTime_AsMilliseconds(PyTime_t ns, _PyTime_round_t round)
843
0
{
844
0
    return pytime_divide(ns, NS_TO_MS, round);
845
0
}
846
847
848
static int
849
pytime_as_timeval(PyTime_t ns, PyTime_t *ptv_sec, int *ptv_usec,
850
                  _PyTime_round_t round)
851
0
{
852
0
    PyTime_t us = pytime_divide(ns, US_TO_NS, round);
853
854
0
    PyTime_t tv_sec, tv_usec;
855
0
    int res = pytime_divmod(us, SEC_TO_US, &tv_sec, &tv_usec);
856
0
    *ptv_sec = tv_sec;
857
0
    *ptv_usec = (int)tv_usec;
858
0
    return res;
859
0
}
860
861
862
static int
863
pytime_as_timeval_struct(PyTime_t t, struct timeval *tv,
864
                         _PyTime_round_t round, int raise_exc)
865
0
{
866
0
    PyTime_t tv_sec;
867
0
    int tv_usec;
868
0
    int res = pytime_as_timeval(t, &tv_sec, &tv_usec, round);
869
0
    int res2;
870
#ifdef MS_WINDOWS
871
    // On Windows, timeval.tv_sec type is long
872
    res2 = _PyTime_AsCLong(tv_sec, &tv->tv_sec);
873
#else
874
0
    res2 = _PyTime_AsTime_t(tv_sec, &tv->tv_sec);
875
0
#endif
876
0
    if (res2 < 0) {
877
0
        tv_usec = 0;
878
0
    }
879
0
    tv->tv_usec = tv_usec;
880
881
0
    if (raise_exc && (res < 0 || res2 < 0)) {
882
0
        pytime_time_t_overflow();
883
0
        return -1;
884
0
    }
885
0
    return 0;
886
0
}
887
888
889
int
890
_PyTime_AsTimeval(PyTime_t t, struct timeval *tv, _PyTime_round_t round)
891
0
{
892
0
    return pytime_as_timeval_struct(t, tv, round, 1);
893
0
}
894
895
896
void
897
_PyTime_AsTimeval_clamp(PyTime_t t, struct timeval *tv, _PyTime_round_t round)
898
0
{
899
0
    (void)pytime_as_timeval_struct(t, tv, round, 0);
900
0
}
901
902
903
int
904
_PyTime_AsTimevalTime_t(PyTime_t t, time_t *p_secs, int *us,
905
                        _PyTime_round_t round)
906
0
{
907
0
    PyTime_t secs;
908
0
    if (pytime_as_timeval(t, &secs, us, round) < 0) {
909
0
        pytime_time_t_overflow();
910
0
        return -1;
911
0
    }
912
913
0
    if (_PyTime_AsTime_t(secs, p_secs) < 0) {
914
0
        pytime_time_t_overflow();
915
0
        return -1;
916
0
    }
917
0
    return 0;
918
0
}
919
920
921
#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
922
static int
923
pytime_as_timespec(PyTime_t ns, struct timespec *ts, int raise_exc)
924
0
{
925
0
    PyTime_t tv_sec, tv_nsec;
926
0
    int res = pytime_divmod(ns, SEC_TO_NS, &tv_sec, &tv_nsec);
927
928
0
    int res2 = _PyTime_AsTime_t(tv_sec, &ts->tv_sec);
929
0
    if (res2 < 0) {
930
0
        tv_nsec = 0;
931
0
    }
932
0
    ts->tv_nsec = tv_nsec;
933
934
0
    if (raise_exc && (res < 0 || res2 < 0)) {
935
0
        pytime_time_t_overflow();
936
0
        return -1;
937
0
    }
938
0
    return 0;
939
0
}
940
941
void
942
_PyTime_AsTimespec_clamp(PyTime_t t, struct timespec *ts)
943
0
{
944
0
    (void)pytime_as_timespec(t, ts, 0);
945
0
}
946
947
int
948
_PyTime_AsTimespec(PyTime_t t, struct timespec *ts)
949
0
{
950
0
    return pytime_as_timespec(t, ts, 1);
951
0
}
952
#endif
953
954
955
// N.B. If raise_exc=0, this may be called without a thread state.
956
static int
957
py_get_system_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
958
16
{
959
16
    assert(info == NULL || raise_exc);
960
16
    if (raise_exc) {
961
        // raise_exc requires to hold a thread state
962
16
        _Py_AssertHoldsTstate();
963
16
    }
964
965
#ifdef MS_WINDOWS
966
    FILETIME system_time;
967
    ULARGE_INTEGER large;
968
969
    GetSystemTimePreciseAsFileTime(&system_time);
970
    large.u.LowPart = system_time.dwLowDateTime;
971
    large.u.HighPart = system_time.dwHighDateTime;
972
973
    PyTime_t ns = (large.QuadPart - SECS_BETWEEN_EPOCHS * HUNDRED_NS_PER_SEC) * 100;
974
    *tp = ns;
975
    if (info) {
976
        // GetSystemTimePreciseAsFileTime() is implemented using
977
        // QueryPerformanceCounter() internally.
978
        info->implementation = "GetSystemTimePreciseAsFileTime()";
979
        info->monotonic = 0;
980
        info->resolution = _PyTimeFraction_Resolution(&_PyRuntime.time.base);
981
        info->adjustable = 1;
982
    }
983
984
#else   /* MS_WINDOWS */
985
16
    int err;
986
16
#if defined(HAVE_CLOCK_GETTIME)
987
16
    struct timespec ts;
988
16
#endif
989
990
#if !defined(HAVE_CLOCK_GETTIME) || defined(__APPLE__)
991
    struct timeval tv;
992
#endif
993
994
16
#ifdef HAVE_CLOCK_GETTIME
995
996
#ifdef HAVE_CLOCK_GETTIME_RUNTIME
997
    if (HAVE_CLOCK_GETTIME_RUNTIME) {
998
#endif
999
1000
16
    err = clock_gettime(CLOCK_REALTIME, &ts);
1001
16
    if (err) {
1002
0
        if (raise_exc) {
1003
0
            PyErr_SetFromErrno(PyExc_OSError);
1004
0
        }
1005
0
        return -1;
1006
0
    }
1007
16
    if (pytime_fromtimespec(tp, &ts, raise_exc) < 0) {
1008
0
        return -1;
1009
0
    }
1010
1011
16
    if (info) {
1012
0
        struct timespec res;
1013
0
        info->implementation = "clock_gettime(CLOCK_REALTIME)";
1014
0
        info->monotonic = 0;
1015
0
        info->adjustable = 1;
1016
0
        if (clock_getres(CLOCK_REALTIME, &res) == 0) {
1017
0
            info->resolution = (double)res.tv_sec + (double)res.tv_nsec * 1e-9;
1018
0
        }
1019
0
        else {
1020
0
            info->resolution = 1e-9;
1021
0
        }
1022
0
    }
1023
1024
#ifdef HAVE_CLOCK_GETTIME_RUNTIME
1025
    }
1026
    else {
1027
#endif
1028
1029
16
#endif
1030
1031
#if !defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_GETTIME_RUNTIME)
1032
1033
     /* test gettimeofday() */
1034
    err = gettimeofday(&tv, (struct timezone *)NULL);
1035
    if (err) {
1036
        if (raise_exc) {
1037
            PyErr_SetFromErrno(PyExc_OSError);
1038
        }
1039
        return -1;
1040
    }
1041
    if (pytime_fromtimeval(tp, &tv, raise_exc) < 0) {
1042
        return -1;
1043
    }
1044
1045
    if (info) {
1046
        info->implementation = "gettimeofday()";
1047
        info->resolution = 1e-6;
1048
        info->monotonic = 0;
1049
        info->adjustable = 1;
1050
    }
1051
1052
#if defined(HAVE_CLOCK_GETTIME_RUNTIME) && defined(HAVE_CLOCK_GETTIME)
1053
    } /* end of availability block */
1054
#endif
1055
1056
#endif   /* !HAVE_CLOCK_GETTIME */
1057
16
#endif   /* !MS_WINDOWS */
1058
16
    return 0;
1059
16
}
1060
1061
1062
int
1063
PyTime_Time(PyTime_t *result)
1064
16
{
1065
16
    if (py_get_system_clock(result, NULL, 1) < 0) {
1066
0
        *result = 0;
1067
0
        return -1;
1068
0
    }
1069
16
    return 0;
1070
16
}
1071
1072
1073
int
1074
PyTime_TimeRaw(PyTime_t *result)
1075
0
{
1076
0
    if (py_get_system_clock(result, NULL, 0) < 0) {
1077
0
        *result = 0;
1078
0
        return -1;
1079
0
    }
1080
0
    return 0;
1081
0
}
1082
1083
1084
int
1085
_PyTime_TimeWithInfo(PyTime_t *t, _Py_clock_info_t *info)
1086
0
{
1087
0
    return py_get_system_clock(t, info, 1);
1088
0
}
1089
1090
1091
#ifdef MS_WINDOWS
1092
static PyStatus
1093
py_win_perf_counter_frequency(_PyTimeFraction *base)
1094
{
1095
    LARGE_INTEGER freq;
1096
    // Since Windows XP, the function cannot fail.
1097
    (void)QueryPerformanceFrequency(&freq);
1098
    LONGLONG frequency = freq.QuadPart;
1099
1100
    // Since Windows XP, frequency cannot be zero.
1101
    assert(frequency >= 1);
1102
1103
    Py_BUILD_ASSERT(sizeof(PyTime_t) == sizeof(frequency));
1104
    PyTime_t denom = (PyTime_t)frequency;
1105
1106
    // Known QueryPerformanceFrequency() values:
1107
    //
1108
    // * 10,000,000 (10 MHz): 100 ns resolution
1109
    // * 3,579,545 Hz (3.6 MHz): 279 ns resolution
1110
    if (_PyTimeFraction_Set(base, SEC_TO_NS, denom) < 0) {
1111
        return _PyStatus_ERR("invalid QueryPerformanceFrequency");
1112
    }
1113
    return PyStatus_Ok();
1114
}
1115
1116
1117
// N.B. If raise_exc=0, this may be called without the GIL.
1118
static int
1119
py_get_win_perf_counter(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
1120
{
1121
    assert(info == NULL || raise_exc);
1122
1123
    if (info) {
1124
        info->implementation = "QueryPerformanceCounter()";
1125
        info->resolution = _PyTimeFraction_Resolution(&_PyRuntime.time.base);
1126
        info->monotonic = 1;
1127
        info->adjustable = 0;
1128
    }
1129
1130
    LARGE_INTEGER now;
1131
    QueryPerformanceCounter(&now);
1132
    LONGLONG ticksll = now.QuadPart;
1133
1134
    /* Make sure that casting LONGLONG to PyTime_t cannot overflow,
1135
       both types are signed */
1136
    PyTime_t ticks;
1137
    static_assert(sizeof(ticksll) <= sizeof(ticks),
1138
                  "LONGLONG is larger than PyTime_t");
1139
    ticks = (PyTime_t)ticksll;
1140
1141
    *tp = _PyTimeFraction_Mul(ticks, &_PyRuntime.time.base);
1142
    return 0;
1143
}
1144
#endif  // MS_WINDOWS
1145
1146
1147
#ifdef __APPLE__
1148
static PyStatus
1149
py_mach_timebase_info(_PyTimeFraction *base)
1150
{
1151
    mach_timebase_info_data_t timebase;
1152
    // According to the Technical Q&A QA1398, mach_timebase_info() cannot
1153
    // fail: https://developer.apple.com/library/mac/#qa/qa1398/
1154
    (void)mach_timebase_info(&timebase);
1155
1156
    // Check that timebase.numer and timebase.denom can be casted to
1157
    // PyTime_t. In practice, timebase uses uint32_t, so casting cannot
1158
    // overflow. At the end, only make sure that the type is uint32_t
1159
    // (PyTime_t is 64-bit long).
1160
    Py_BUILD_ASSERT(sizeof(timebase.numer) <= sizeof(PyTime_t));
1161
    Py_BUILD_ASSERT(sizeof(timebase.denom) <= sizeof(PyTime_t));
1162
    PyTime_t numer = (PyTime_t)timebase.numer;
1163
    PyTime_t denom = (PyTime_t)timebase.denom;
1164
1165
    // Known time bases:
1166
    //
1167
    // * (1, 1) on Intel: 1 ns
1168
    // * (1000000000, 33333335) on PowerPC: ~30 ns
1169
    // * (1000000000, 25000000) on PowerPC: 40 ns
1170
    if (_PyTimeFraction_Set(base, numer, denom) < 0) {
1171
        return _PyStatus_ERR("invalid mach_timebase_info");
1172
    }
1173
    return PyStatus_Ok();
1174
}
1175
#endif
1176
1177
PyStatus
1178
_PyTime_Init(struct _Py_time_runtime_state *state)
1179
36
{
1180
#ifdef MS_WINDOWS
1181
    return py_win_perf_counter_frequency(&state->base);
1182
#elif defined(__APPLE__)
1183
    return py_mach_timebase_info(&state->base);
1184
#else
1185
36
    return PyStatus_Ok();
1186
36
#endif
1187
36
}
1188
1189
// N.B. If raise_exc=0, this may be called without a thread state.
1190
static int
1191
py_get_monotonic_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
1192
196k
{
1193
196k
    assert(info == NULL || raise_exc);
1194
196k
    if (raise_exc) {
1195
        // raise_exc requires to hold a thread state
1196
34.2k
        _Py_AssertHoldsTstate();
1197
34.2k
    }
1198
1199
#if defined(MS_WINDOWS)
1200
    if (py_get_win_perf_counter(tp, info, raise_exc) < 0) {
1201
        return -1;
1202
    }
1203
#elif defined(__APPLE__)
1204
    if (info) {
1205
        info->implementation = "mach_absolute_time()";
1206
        info->resolution = _PyTimeFraction_Resolution(&_PyRuntime.time.base);
1207
        info->monotonic = 1;
1208
        info->adjustable = 0;
1209
    }
1210
1211
    uint64_t uticks = mach_absolute_time();
1212
    // unsigned => signed
1213
    assert(uticks <= (uint64_t)PyTime_MAX);
1214
    PyTime_t ticks = (PyTime_t)uticks;
1215
1216
    PyTime_t ns = _PyTimeFraction_Mul(ticks, &_PyRuntime.time.base);
1217
    *tp = ns;
1218
1219
#elif defined(__hpux)
1220
    hrtime_t time = gethrtime();
1221
    if (time == -1) {
1222
        if (raise_exc) {
1223
            PyErr_SetFromErrno(PyExc_OSError);
1224
        }
1225
        return -1;
1226
    }
1227
1228
    *tp = time;
1229
1230
    if (info) {
1231
        info->implementation = "gethrtime()";
1232
        info->resolution = 1e-9;
1233
        info->monotonic = 1;
1234
        info->adjustable = 0;
1235
    }
1236
1237
#else
1238
1239
#ifdef CLOCK_HIGHRES
1240
    const clockid_t clk_id = CLOCK_HIGHRES;
1241
    const char *implementation = "clock_gettime(CLOCK_HIGHRES)";
1242
#else
1243
196k
    const clockid_t clk_id = CLOCK_MONOTONIC;
1244
196k
    const char *implementation = "clock_gettime(CLOCK_MONOTONIC)";
1245
196k
#endif
1246
1247
196k
    struct timespec ts;
1248
196k
    if (clock_gettime(clk_id, &ts) != 0) {
1249
0
        if (raise_exc) {
1250
0
            PyErr_SetFromErrno(PyExc_OSError);
1251
0
            return -1;
1252
0
        }
1253
0
        return -1;
1254
0
    }
1255
1256
196k
    if (pytime_fromtimespec(tp, &ts, raise_exc) < 0) {
1257
0
        return -1;
1258
0
    }
1259
1260
196k
    if (info) {
1261
0
        info->monotonic = 1;
1262
0
        info->implementation = implementation;
1263
0
        info->adjustable = 0;
1264
0
        struct timespec res;
1265
0
        if (clock_getres(clk_id, &res) != 0) {
1266
0
            PyErr_SetFromErrno(PyExc_OSError);
1267
0
            return -1;
1268
0
        }
1269
0
        info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
1270
0
    }
1271
196k
#endif
1272
196k
    return 0;
1273
196k
}
1274
1275
1276
int
1277
PyTime_Monotonic(PyTime_t *result)
1278
34.2k
{
1279
34.2k
    if (py_get_monotonic_clock(result, NULL, 1) < 0) {
1280
0
        *result = 0;
1281
0
        return -1;
1282
0
    }
1283
34.2k
    return 0;
1284
34.2k
}
1285
1286
1287
int
1288
PyTime_MonotonicRaw(PyTime_t *result)
1289
162k
{
1290
162k
    if (py_get_monotonic_clock(result, NULL, 0) < 0) {
1291
0
        *result = 0;
1292
0
        return -1;
1293
0
    }
1294
162k
    return 0;
1295
162k
}
1296
1297
1298
int
1299
_PyTime_MonotonicWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
1300
0
{
1301
0
    return py_get_monotonic_clock(tp, info, 1);
1302
0
}
1303
1304
1305
int
1306
_PyTime_PerfCounterWithInfo(PyTime_t *t, _Py_clock_info_t *info)
1307
0
{
1308
0
    return _PyTime_MonotonicWithInfo(t, info);
1309
0
}
1310
1311
1312
int
1313
PyTime_PerfCounter(PyTime_t *result)
1314
34.2k
{
1315
34.2k
    return PyTime_Monotonic(result);
1316
34.2k
}
1317
1318
1319
int
1320
PyTime_PerfCounterRaw(PyTime_t *result)
1321
162k
{
1322
162k
    return PyTime_MonotonicRaw(result);
1323
162k
}
1324
1325
1326
int
1327
_PyTime_localtime(time_t t, struct tm *tm)
1328
72
{
1329
#ifdef MS_WINDOWS
1330
    if (t >= 0) {
1331
        /* For non-negative timestamps, use localtime_s() */
1332
        int error = localtime_s(tm, &t);
1333
        if (error != 0) {
1334
            errno = error;
1335
            PyErr_SetFromErrno(PyExc_OSError);
1336
            return -1;
1337
        }
1338
        return 0;
1339
    }
1340
1341
    /* For negative timestamps, use FILETIME-based conversion */
1342
    return _PyTime_windows_filetime(t, tm, 1);
1343
#else /* !MS_WINDOWS */
1344
1345
#if defined(_AIX) && (SIZEOF_TIME_T < 8)
1346
    /* bpo-34373: AIX does not return NULL if t is too small or too large */
1347
    if (t < -2145916800 /* 1902-01-01 */
1348
       || t > 2145916800 /* 2038-01-01 */) {
1349
        errno = EINVAL;
1350
        PyErr_SetString(PyExc_OverflowError,
1351
                        "localtime argument out of range");
1352
        return -1;
1353
    }
1354
#endif
1355
1356
72
    errno = 0;
1357
72
    if (localtime_r(&t, tm) == NULL) {
1358
0
        if (errno == 0) {
1359
0
            errno = EINVAL;
1360
0
        }
1361
0
        PyErr_SetFromErrno(PyExc_OSError);
1362
0
        return -1;
1363
0
    }
1364
72
    return 0;
1365
72
#endif /* MS_WINDOWS */
1366
72
}
1367
1368
1369
int
1370
_PyTime_gmtime(time_t t, struct tm *tm)
1371
0
{
1372
#ifdef MS_WINDOWS
1373
    /* For non-negative timestamps, use gmtime_s() */
1374
    if (t >= 0) {
1375
        int error = gmtime_s(tm, &t);
1376
        if (error != 0) {
1377
            errno = error;
1378
            PyErr_SetFromErrno(PyExc_OSError);
1379
            return -1;
1380
        }
1381
        return 0;
1382
    }
1383
1384
    /* For negative timestamps, use FILETIME-based conversion */
1385
    return _PyTime_windows_filetime(t, tm, 0);
1386
#else /* !MS_WINDOWS */
1387
0
    if (gmtime_r(&t, tm) == NULL) {
1388
0
#ifdef EINVAL
1389
0
        if (errno == 0) {
1390
0
            errno = EINVAL;
1391
0
        }
1392
0
#endif
1393
0
        PyErr_SetFromErrno(PyExc_OSError);
1394
0
        return -1;
1395
0
    }
1396
0
    return 0;
1397
0
#endif /* MS_WINDOWS */
1398
0
}
1399
1400
1401
PyTime_t
1402
_PyDeadline_Init(PyTime_t timeout)
1403
0
{
1404
0
    PyTime_t now;
1405
    // silently ignore error: cannot report error to the caller
1406
0
    (void)PyTime_MonotonicRaw(&now);
1407
0
    return _PyTime_Add(now, timeout);
1408
0
}
1409
1410
1411
PyTime_t
1412
_PyDeadline_Get(PyTime_t deadline)
1413
0
{
1414
0
    PyTime_t now;
1415
    // silently ignore error: cannot report error to the caller
1416
0
    (void)PyTime_MonotonicRaw(&now);
1417
0
    return deadline - now;
1418
0
}