How Windows stores time.
There are two binary types. One is the count of 100 ns periods in two
DWORDs, called FileTime. The other is a number for the year, month, day of
month, hour, minute, second and milliseconds each in a WORD (unsigned 16 bit
type) called SystemTime. It also has a WORD for the day-of-week ID.
Range of FileTime and SystemTime.
The "epoch" for Windows NT family of operating systems (OSs) is
1 January 16011, 2 and 3 and ranges to the maximum/latest/largest
for each type. Zero in FileTime is midnight on 1 January 1601. The
first/earliest SystemTime is 1601, 01, 01, 0, 0, 0 and 0. For input to a
SystemTime, do not use day-of-week. That will take the next discussion to
describe.
Largest/Latest Date-Times for FileTime and SystemTime
In a FileTime bit 63 is never "set". That would indicate a negative
value in a signed type. Microsoft mentions __int64* (a signed type) on their
FileTime page1. So, the maximum value for a FileTime is
7FFFFFFFFFFFFFFF16. That value plus one causes FileTimeToSystemTime
1 to error. (Source code for a
PB Demo"
of maximum FileTime and SystemTime.) That represents
30828-09-14T02:48:05.4775807Z (in ISO 8601 format) The latest date where
function SystemTimeToFileTime2 does not fail is:
30827-12-31T23:59:59.999Z or 7FFF35F4F06C58F016 for the equivalent
FileTime value. Since 30827-12-31T23:59:59.999Z works in both directions, I'll
call that the maximum "usable" Date-Time for Windows. (30827 - 2023 is 28804
years. There is nothing to worry about any time soon. 😄 )
Use of QUAD instead of FileTime in PB.
Microsoft recommends against doing arithmatic operations on variables of
type FileTime1 Also, "Do not cast a FILETIME
pointer to either a ULARGE_INTEGER* or __int64* value because it can cause
alignment faults on 64-bit Windows."; __int64* is C++ equivelent of PB's
QUAD. (PB compiled programs operate in 32 bit environment in 64 bit Windows,
but why form bad habits?) I dislike the extra step of copying as Microsoft
suggests. They do not say anything about the rerverse, using a pointer of a
QUAD with API functions that need a FILETIME pointer. A way to do this is a
UNION of QUAD and FileTime; PB includes in \WinAPI\ directory has one defined.
The "AS FILETIME" in a function call could be changed to "AS QUAD" in the
include files, or a copy of the DECLARE in the source code, or by putting
"BYVAL VARPTR(varname AS DWORD" in the call statement.
Resolution of FileTime and SystemTime.
Even though a FileTime, or its timer are used for many functions, the
resolution is in the milliseconds. Even though the low bits eventually change
in a FileTime variable, it is updated in "steps" of multiple milliseconds.
Raymond Chen4 (see footnote 4) explains it well. The times used in
the file system (CreationTime, LastAccessTime and LastWriteTime) are a second
or worse. GetSystemTime and the SystemTime type only resolve down to
milliseconds or multiple milliseconds. If you use
GetSystemTimePreciseAsFileTime, then FileTimeToSystemTime, ignore the
milliseconds member, do MOD 1000000010 on the FileTime, and append
the result you get (upto) a 10010 ns resolution time stamp string.
(method shown at end of
PB Demo" source code)
PowerBASIC Time Related Functions / Statements.
Created on 19 March 2023
To Domain Home. | To Dale's Notebook index. | To Programs index. |