For precision timing in Python:
1. Python 3.7 or later
If using Python 3.7 or later, use the modern, cross-platform time
module functions such as time.monotonic_ns()
, here: https://docs.python.org/3/library/time.html#time.monotonic_ns. It provides nanosecond-resolution timestamps.
import time
time_ns = time.monotonic_ns() # note: unspecified epoch
# or on Unix or Linux you can also use:
time_ns = time.clock_gettime_ns()
# or on Windows:
time_ns = time.perf_counter_ns()
# etc. etc. There are others. See the link above.
See also this note from my other answer from 2016, here: How can I get millisecond and microsecond-resolution timestamps in Python?:
You might also try time.clock_gettime_ns()
on Unix or Linux systems. Based on its name, it appears to call the underlying clock_gettime()
C function which I use in my nanos()
function in C in my answer here and in my C Unix/Linux library here: timinglib.c.
Unspecified epoch:
Note that when using time.monotonic()
or time.monotonic_ns()
, the official documentation says:
The reference point of the returned value is undefined, so that only the difference between the results of two calls is valid.
So, if you need an absolute datetime type timestamp instead of a precision relative timestamp, which absolute datetime contains information like year, month, date, etc., then you should consider using datetime
instead. See this answer here, my comment below it, and the official datetime
documentation here and specifically for datetime.now()
here. Here is how to get a timestamp with that module:
from datetime import datetime
now_datetime_object = datetime.now()
Do not expect it to have the resolution nor precision nor monotonicity of time.clock_gettime_ns()
, however. So, for timing small differences or doing precision timing work, prefer time.clock_gettime_ns()
instead.
Another option is time.time()
--also not guaranteeed to have a "better precision than 1 second". You can convert it back to a datetime using time.localtime()
or time.gmtime()
. See here. Here's how to use it:
>>> import time
>>> time.time()
1691442858.8543699
>>> time.localtime(time.time())
time.struct_time(tm_year=2023, tm_mon=8, tm_mday=7, tm_hour=14, tm_min=14, tm_sec=36, tm_wday=0, tm_yday=219, tm_isdst=0)
Or, even better: time.time_ns()
:
>>> import time
>>> time.time_ns()
1691443244384978570
>>> time.localtime(time.time_ns()/1e9)
time.struct_time(tm_year=2023, tm_mon=8, tm_mday=7, tm_hour=14, tm_min=20, tm_sec=57, tm_wday=0, tm_yday=219, tm_isdst=0)
>>> time.time_ns()/1e9
1691443263.0889063
2. Python 3.3 or later
On Windows, in Python 3.3 or later, you can use time.perf_counter()
, as shown by @ereOn here. See: https://docs.python.org/3/library/time.html#time.perf_counter. This provides roughly a 0.5us-resolution timestamp, in floating point seconds. Ex:
import time
# For Python 3.3 or later
time_sec = time.perf_counter() # Windows only, I think
# or on Unix or Linux (I think only those)
time_sec = time.monotonic()
3. Pre-Python 3.3 (ex: Python 3.0, 3.1, 3.2), or later
Summary:
See my other answer from 2016 here for 0.5-us-resolution timestamps, or better, in Windows and Linux, and for versions of Python as old as 3.0, 3.2 or 3.2 even! We do this by calling C or C++ shared object libraries (.dll on Windows, or .so on Unix or Linux) using the ctypes
module in Python.
I provide these functions:
millis()
micros()
delay()
delayMicroseconds()
Download GS_timing.py
from my eRCaGuy_PyTime repo, then do:
import GS_timing
time_ms = GS_timing.millis()
time_us = GS_timing.micros()
GS_timing.delay(10) # delay 10 ms
GS_timing.delayMicroseconds(10000) # delay 10000 us
Details:
In 2016, I was working in Python 3.0 or 3.1, on an embedded project on a Raspberry Pi, and which I tested and ran frequently on Windows also. I needed nanosecond resolution for some precise timing I was doing with ultrasonic sensors. The Python language at the time did not provide this resolution, and neither did any answer to this question, so I came up with this separate Q&A here: How can I get millisecond and microsecond-resolution timestamps in Python?. I stated in the question at the time:
I read other answers before asking this question, but they rely on the time
module, which prior to Python 3.3 did NOT have any type of guaranteed resolution whatsoever. Its resolution is all over the place. The most upvoted answer here quotes a Windows resolution (using their answer) of 16 ms, which is 32000 times worse than my answer provided here (0.5 us resolution). Again, I needed 1 ms and 1 us (or similar) resolutions, not 16000 us resolution.
Zero, I repeat: zero answers here on 12 July 2016 had any resolution better than 16-ms for Windows in Python 3.1. So, I came up with this answer which has 0.5us or better resolution in pre-Python 3.3 in Windows and Linux. If you need something like that for an older version of Python, or if you just want to learn how to call C or C++ dynamic libraries in Python (.dll "dynamically linked library" files in Windows, or .so "shared object" library files in Unix or Linux) using the ctypes
library, see my other answer here.