Skip to content

Instantly share code, notes, and snippets.

@jun66j5
Created January 12, 2016 11:20
Show Gist options
  • Save jun66j5/98b503c6ba3317df03a5 to your computer and use it in GitHub Desktop.
Save jun66j5/98b503c6ba3317df03a5 to your computer and use it in GitHub Desktop.
High-resolution system time on Windows 8+ and Windows Server 2012+
from ctypes import Structure, pointer, windll
from ctypes.wintypes import DWORD, WORD
from datetime import datetime
class FILETIME(Structure):
_fields_ = [('dwLowDateTime', DWORD),
('dwHighDateTime', DWORD)]
_kernel32 = windll.kernel32
GetLastError = _kernel32.GetLastError
SystemTimeToFileTime = _kernel32.SystemTimeToFileTime
try:
# available in Windows 8+ and Windows Server 2012+
get_systime = _kernel32.GetSystemTimePreciseAsFileTime
func_systime = 'GetSystemTimePreciseAsFileTime'
except AttributeError:
get_systime = _kernel32.GetSystemTimeAsFileTime
func_systime = 'GetSystemTimeAsFileTime'
def _get_filetime_epoch():
class SYSTEMTIME(Structure):
_fields_ = [('wYear', WORD),
('wMonth', WORD),
('wDayOfWeek', WORD),
('wDay', WORD),
('wHour', WORD),
('wMinute', WORD),
('wSecond', WORD),
('wMilliseconds', WORD)]
st = SYSTEMTIME()
st.wYear = 1970
st.wMonth = 1
st.wDay = 1
st.wDayOfWeek = 0
st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0
ft = FILETIME()
if SystemTimeToFileTime(pointer(st), pointer(ft)):
return ft.dwHighDateTime * 0x100000000L + ft.dwLowDateTime
else:
raise RuntimeError('[LastError SystemTimeToFileTime %d]' %
GetLastError())
_filetime_epoch = _get_filetime_epoch()
def now(tz=None):
ft = FILETIME()
if not get_systime(pointer(ft)):
raise RuntimeError('[LastError %s %d]' %
(func_systime, GetLastError()))
ft = ft.dwHighDateTime * 0x100000000L + ft.dwLowDateTime
usec = (ft - _filetime_epoch) / 10L
return datetime.fromtimestamp(usec / 1000000.0, tz)
def test_now(f, n):
print('\n'.join(f().isoformat() for i in xrange(n)))
n = 5
print('datetime.now:')
test_now(datetime.now, n)
print
print(func_systime + ':')
test_now(now, n)
@jun66j5
Copy link
Author

jun66j5 commented Jan 12, 2016

Results:

datetime.now:
2016-01-12T20:18:51.314000
2016-01-12T20:18:51.314000
2016-01-12T20:18:51.314000
2016-01-12T20:18:51.314000
2016-01-12T20:18:51.314000

GetSystemTimePreciseAsFileTime:
2016-01-12T20:18:51.323156
2016-01-12T20:18:51.323178
2016-01-12T20:18:51.323185
2016-01-12T20:18:51.323192
2016-01-12T20:18:51.323198

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment