Hello everybody! I'm trying to produce a timestamp (system time) in windows (Python 2.7) with resolution equal to or better than microseconds. Calling time.time() repeatedly in a loop it appears it only updates in approximately 0.01 second increments. Using datetime.datetime.today() seems to show similar results. Anybody have a possible way of getting a better timestamp?

Thanks in advance!

Dani AI

Generated

Short answer: anchor a high-resolution performance counter (QueryPerformanceCounter) to a system-time snapshot and use the counter for microsecond-accurate elapsed time, adding that elapsed to the snapshot to get a high-resolution wall-clock timestamp.

time.time()/datetime.now() show coarse updates on many Windows systems; was right that the Windows high-res timer is available, but as noted it is a relative timer, not the system clock. On Windows Python 2.7’s time.clock() is implemented on top of QueryPerformanceCounter and therefore has very high resolution, but it does not by itself give a UTC wall-clock value. (docs.python.org)

Recommended workflow (robust and simple):

  1. At program start capture QueryPerformanceFrequency and a base QueryPerformanceCounter tick.
  2. Immediately capture a wall-clock snapshot using GetSystemTimePreciseAsFileTime (Windows 8+) or GetSystemTimeAsFileTime otherwise.
  3. Convert the FILETIME snapshot to Unix seconds and save as base_time.
  4. For each timestamp read QueryPerformanceCounter, compute elapsed = (now_ticks - base_ticks)/frequency, then timestamp = base_time + elapsed.
    Do a periodic resync (or when you detect large drift) because QPC is not tied to UTC and some platforms/VMs can exhibit anomalies; use the precise system API when available for best wall-clock anchoring. (learn.microsoft.com)

Quick Python 2.7 pattern (ctypes):

# Python 2.7 - init once, then call highres_timestamp()
import ctypes
EPOCH_AS_FILETIME = 116444736000000000  # 100-ns intervals (1601->1970)
HUNDREDS_NS = 1e-7
kernel32 = ctypes.windll.kernel32
freq = ctypes.c_longlong()
kernel32.QueryPerformanceFrequency(ctypes.byref(freq))

class FILETIME(ctypes.Structure):
    _fields_ = [("dwLowDateTime", ctypes.c_uint32), ("dwHighDateTime", ctypes.c_uint32)]

def _filetime_to_unix(ft):
    v = (ft.dwHighDateTime << 32) + ft.dwLowDateTime
    return (v - EPOCH_AS_FILETIME) * HUNDREDS_NS

def init_anchor():
    base_qpc = ctypes.c_longlong(); kernel32.QueryPerformanceCounter(ctypes.byref(base_qpc))
    ft = FILETIME()
    func = getattr(kernel32, "GetSystemTimePreciseAsFileTime", None)
    if func:
        func(ctypes.byref(ft))
    else:
        kernel32.GetSystemTimeAsFileTime(ctypes.byref(ft))
    return base_qpc.value, _filetime_to_unix(ft), freq.value

BASE_QPC, BASE_TIME, QPF = init_anchor()

def highres_timestamp():
    now = ctypes.c_longlong(); kernel32.QueryPerformanceCounter(ctypes.byref(now))
    return BASE_TIME + (now.value - BASE_QPC) / float(QPF)

Notes and cautions: resync periodically or when NTP/system time jumps occur; on older Windows versions or some virtualized environments QPC can behave oddly (±1 tick ambiguity or rare leaps), so validate ordering if you need strict monotonic guarantees. If you can use Python 3, prefer time.perf_counter_ns() for interval timing and time.time_ns() for wall-clock values, still anchoring perf_counter to a precise system-time snapshot if you need high-resolution, UTC-synced timestamps. (learn.microsoft.com)

Recommended Answers

All 6 Replies

time.clock() gives more accurate time in Windows.

It has better resolution as a timer but it doesn't give you the system time. If I could get time.clock's resolution in a timestamp I would be happy. I was considering trying to use time.clock in combination with one of the system time's to try and improve the system time resolution but not sure where to start.

Maybe you coul do own format string for today datetime object.

It's not a problem to display more precision in the timestamp. Both of the methods I mentioned above show high precision (datetime object has microsecond attribute), but if you call it many times in a loop you will see it only updates that value every 0.01 seconds making it a lot of useless precision. I need a high resolution timer coupled with the timestamp so I can actually compare timestamps at the microsecond level.

It looks like calling the windows API QueryPerformanceCounter() and QueryPerformanceFrequency() functions is what I am looking for, if I can tie it in to the actual time:

http://www.grahamwideman.com/gw/tech/dataacq/wintiming.htm

I'm thinking I will try to zero my precise timer with the system time updates so I can count time with ticks.

Thanks for the responses pyTony. Any ideas would still be appreciated.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.