Found GetSystemTimePreciseAsFileTime() while poking around at learn.microsoft.com for an improved interval counter procedure in the API. The time won't be any more accurate than what the PC is set to. Maybe ± 25 ms if synchronized over the Internet. Better if set a GPS receiver's time. Better still if you have an atomic clock in your home or office. 😀
If the time is only accurate to tens of milliseconds, How is resolution to a hundred nanoseconds useful? An advantage is you will get is that two time stamps always will be different on a particular PC (sequence maintenance). If PCs are on a local network (LAN) it should be possible to synchronize them within microseconds. 😎
First is QueryPerformanceFrequency. It returns the current performance-counter frequency in counts per second (Hz). A frequency of 10000000 (10 MHz) has a period of 100 ns, the value of the least significant bit in a FileTime type.
The improved resolution of GetSystemTimePreciseAsFileTime is
shown by comparison with GetSystemTimeAsFileTime. Each is called successively
and the time differences displayed. A difference of zero indicates the
resolution is greater than the time to immediately repeat the call (bad). The
sequence of the time stamps can not be determined by the values contained.
Any difference greater than zero means there will be no duplicate time
stamps (good).
Note - Instead of variables typed as UDT FileTime, QUAD type is used. This
eliminates need for a FileTime/QUAD UNION.
Getting the entire time stamp to human readable form is the last
thing performed in the demo app. Convert the FileTime to a SystemTime. By not
using the wMilliseconds and MODing the FileTime by 10000000 an integer that
can be concatenated after the decimal point in one step. wDayOfWeek not used
here.
For local time use FileTimeToLocalFileTime before FileTimeToSystemTime.
The DECLARE for SUB GetSystemTimePreciseAsFileTime is not in PBWin 10's, nor PBCC 06's, or older, \WinAPI\ include files. Keep for future use! It was new in Windows 8. It probably would have been in the include files for PBWin 11 and PBCC 7 if they had been produced (at the time).
#compile exe #dim all #if %pb_cc32 'This ignored by PBWin, stops creation of unneeded console in PBCC. #console off #endif 'As with the DECLARES, so you can see it here. type SYSTEMTIME wYear as word wMonth as word wDayOfWeek as word wDay as word wHour as word wMinute as word wSecond as word wMilliseconds as word end type 'DECLARES here so you don't have to look in the include files to "follow the 'action". Microsoft defined parameters as BYVAL pointers, that is why the 'variable names have "lp" even though the PB includes use BYREF meaning you 'use the base variable names and PB supplies the pointer. declare function QueryPerformanceFrequency lib "Kernel32.dll" _ alias "QueryPerformanceFrequency" (lpFrequency as quad) as long declare sub GetSystemTimeAsFileTime lib "Kernel32.dll" _ alias "GetSystemTimeAsFileTime" (lpFileTime as quad) 'was "AS FILETIME" declare function FileTimeToSystemTime lib "Kernel32.dll" _ alias "FileTimeToSystemTime" (lpFileTime as quad), _ 'was "AS FILETIME" lpSystemTime as SYSTEMTIME) as long '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'Reminder - This DECLARE is not in the PB \WinAPI\ include files. declare sub GetSystemTimePreciseAsFileTime lib "Kernel32.dll" _ alias "GetSystemTimePreciseAsFileTime" (FTime as quad) ' function pbmain () as long local Freq, UTC_FTime1, UTC_FTime2 as quad local hTxt as dword local UTC_STime as systemtime txt.window("Demo HR Timestamp", 100, 100, 25, 80) to hTxt txt.print "Curious about frequency my PC uses for "; txt.print "high res time stamp and interval." QueryPerformanceFrequency Freq txt.print dec$(Freq); txt.print " 10 Mhz on my PC. That is 100 ns per cycle. (hint, hint)." txt.print string$$(80, &h2550) txt.print "Difference between two consecutive calls." sleep 0 'do test in fresh time slice GetSystemTimePreciseAsFileTime UTC_FTime1 GetSystemTimePreciseAsFileTime UTC_FTime2 txt.print dec$(UTC_FTime2 - UTC_FTime1) + " Precise. I get 2 to 4 here." sleep 0 'do test in fresh time slice GetSystemTimeAsFileTime UTC_FTime1 GetSystemTimeAsFileTime UTC_FTime2 txt.print dec$(UTC_FTime2 - UTC_FTime1) + _ " Old. Always zero due to coarse resolution." txt.print "GetSystemTimeAsFileTime() could return the same for ~15+ ms." txt.print string$$(80, &h2550) txt.print "Two forms of human readable time." GetSystemTimePreciseAsFileTime UTC_FTime1 txt.print dec$(UTC_FTime1) + _ " Current UTC time in decimal of FileTime format." FileTimeToSystemTime UTC_FTime1, UTC_STime txt.print dec$(UTC_STime.wYear, 4) + "-" + dec$(UTC_STime.wMonth, 2) + "-"; txt.print dec$(UTC_STime.wDay, 2) + "T"; txt.print dec$(UTC_STime.wHour, 2) + ":" + dec$(UTC_STime.wMinute, 2) + ":"; txt.print dec$(UTC_STime.wSecond, 2) + "."; txt.print dec$(UTC_FTime1 mod 10000000, 7) + "Z"; txt.print " Current UTC in ISO 8601 format." txt.print string$$(80, &h2550) txt.print txt.print "Any key to exit." txt.waitkey$ end function
Created on 14 March 2023, last edit 15 March 2023.
To
Domain Home. | To Dale's Notebook index. | To Programs index. |