New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pytime.c loses precision under Windows #63937
Comments
Under Windows, GetSystemTimeAsFileTime has a 100 ns resolution, but pygettimeofday stores it in a timeval which only has microsecond resolution. As a consequence, some precision is lost under Windows (which shows e.g. in time.time() results). |
Just noting for the record that a C double (time.time() result) isn't quite enough to hold a full-precision Windows time regardless: >>> from datetime import date
>>> d = date.today() - date(1970, 1, 1)
>>> s = int(d.total_seconds()) # seconds into "the epoch"
>>> s *= 10**7 # number of 100ns into the epoch
>>> s.bit_length()
54
>>> 54 > 53 # QED ;-)
True |
Perhaps we need a time_ns() method? (returning an integer timestamp in nanoseconds) |
I think this issue can be resolved by reducing the loss to the maximum available precision; it's about time.time(), after all. I don't think pygettimeofday can change; gettimeofday traditionally has only µs. So the issue really is that it is used in implementing time.time(). As for whether an integer-returning current-time function in Python is needed: -1 (but then, I voiced the same concern when the ns-filestamp APIs where added). Adding an API will "force" people to rewrite their code, with no real improvement for practical improvement. The "force" comes from the mere availability of the API, and any emerging claims that using the time_ns() function is "more correct". I really wish Python would have a 128-bit floating point type that could be used to represent a time stamp. Until such a type is available (perhaps in 2025), I propose that we live with limitations of 64-bit floating point. Anybody *really* needing the Windows system time can use ctypes (or pywin32) already. |
I agree overall with Martin, although time.time() could be made a little better on Windows by getting the Windows time directly (instead of "needlessly" losing info by going thru pygettimeofday). |
Martin: I think the best choice would be a decimal object--which, now that we have decimal in C, is probably sufficiently performant for serious consideration. |
This idea was rejected: see the PEP-410 :-) |
Victor, is this issue still relevant given your recent work on time? |
In Python 3.3, I modified time.time() to use GetSystemTimeAsFileTime() instead of gettimeofday(). In Python 3.5, I replaced _PyTime_gettimeofday(_PyTime_timeval *tp) (resolution of 1 us) with _PyTime_t _PyTime_GetSystemClock(void) (resolution of 1 ns). Moreover, most Python functions now use internally a monotonic clock (_PyTime_GetMonotonicClock) instead of the system clock (_PyTime_GetSystemClock), especially to compute timeout. Python 3.5 now ensures that a monotonic clock is available, it checks once at runtime (during Python startup). The initial issue "pytime.c loses precision under Windows" has been fixed in the issue bpo-22117 which introduced the _PyTime_t type. The resolution of _PyTime_t is no more hardcoded in the API. Currently, it uses a resolution of 1 nanosecond, but it may be worse if we get compilation issues (no 64 bits signed integer type, too bad) or better (ex: if a compiler supports 128 bits signed integer type, I didn't try __int128 of GCC). The resolution is only handled in pytime.c, not in the users of the API.
This change has been discussed in the PEP-410 which has been rejected. datetime.datetime.now() now uses _PyTime_GetSystemClock() and so indirectly GetSystemTimeAsFileTime() on Windows. Since the datetime type may get nanosecond resolution (issue bpo-15443), it will be possible to get the current time with nanosecond resolution ;-) I now close the issue. |
Oh, I missed this message. The current trend in Python (os.stat) is to use a number of nanoseconds to store a timestamp. If we continue this trend in the datetime module, maybe with a new total_nanoseconds() method for example, it may make sense to add a new time.time_ns() function. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: