FILETIME is a 64 bit type for containing a date-time in 100 ns periods elapsed since 1 January 1601 UTC (the "epoch") 1. The type is made of 2 DWORDs, so is unsigned (no negatives). Microsoft recommends not doing arithmetic with the FILETIME type. They suggest LARGE_INTEGER2 or INT643 That are signed 64 bit types, FILETIME does not use bit 63 (sign bit), so no "acidental" negatives.
The FILETIME page1 also states "Do not cast a pointer to a FILETIME structure to either a ULARGE_INTEGER or _INT64 value ..." (the PB equivalent is the QUAD). It does not say don't do the reverse. I define a QUAD, and pass its pointer to API functions using FILETIME. Let Windows put the number in a 64 bit variable that is already "aligned". Since I usually lookup the DECLARE statement in the include anyway, I copy it to my source changing it to BYREF var_name AS QUAD (more than 4 API functions is rare for me). (you may change function's name, do not change the ALIAS)
Popup list of FILETIME functions/subs (suggestions for additions to the list will be appreciated), the list.
The "Human Units" column to help show that time and date are not defined by groups of bits. This is because of decimal numbers and 60, 60, 24 unit steps don't come out evenly in binary (always just twice the previous). And though bit 58 is the most significant bit for 2024, there will not be a "Year 2K" kind of problem for 28804 more years.
Bit Number | Weight Of Bit nanoSeconds | Human Units (approx.) |
---|---|---|
00 | 100 | 100 ns † |
01 | 200 | 200 ns † |
02 | 400 | 400 ns † |
03 | 800 | 800 ns † |
04 | 1600 | 1.6 µs † |
05 | 3200 | 3.2 µs † |
06 | 6400 | 6.2 µs † |
07 | 12800 | 12.8 µs † |
08 | 25600 | 25.6 µs † |
09 | 51200 | 51.2 µs † |
10 | 102400 | 102 µs |
11 | 204800 | 204 µs |
12 | 409600 | 409 µs |
13 | 819200 | 819 µs |
14 | 1638400 | 1.63 ms |
15 | 3276800 | 3.27 ms |
16 | 6553600 | 6.55 ms |
17 | 13107200 | 13.1 ms |
18 | 26214400 | 26.2 ms |
19 | 52428800 | 52.4 ms |
20 | 104857600 | 104 ms |
21 | 209715200 | 209 ms |
22 | 419430400 | 419 ms |
23 | 838860800 | 838 ms |
24 | 1677721600 | 1.67 s |
25 | 3355443200 | |
26 | 6710886400 | |
27 | 13421772800 | |
28 | 26843545600 | |
29 | 53687091200 | 0.894 minutes |
30 | 107374182400 | 1.79 minutes |
31 | 214748364800 | |
32 | 429496729600 | |
33 | 858993459200 | |
34 | 1717986918400 | |
35 | 3435973836800 | 0.954 hours |
36 | 6871947673600 | |
37 | 13743895347200 | |
38 | 27487790694400 | |
39 | 54975581388800 | |
40 | 109951162777600 | 1.27 days |
41 | 219902325555200 | |
42 | 439804651110400 | |
43 | 879609302220800 | 1.45 weeks |
44 | 1759218604441600 | |
45 | 3518437208883200 | 1.32 months |
46 | 7036874417766400 | |
47 | 14073748835532800 | |
48 | 28147497671065600 | |
49 | 56294995342131200 | 1.78 years |
50 | 112589990684262400 | |
51 | 225179981368524800 | |
52 | 450359962737049600 | 1.43 decades |
53 | 900719925474099200 | |
54 | 1801439850948198400 | |
55 | 3602879701896396800 | 1.14 centuries |
56 | 7205759403792793600 | |
57 | 14411518807585587200 | |
58 | 28823037615171174400 | hi bit of 2024 |
59 | 57646075230342348800 | |
60 | 115292150460684697600 | |
61 | 230584300921369395200 | |
62 | 461168601842738790400 | hi bit of 30827 ‡ |
The FOR/NEXT stop is not 64 because first bit is named "0". It is not 63 because in a QUAD that is the sign bit, and FILETIME is (should) never be negative (discussed at top of page). BitArray(0) is set to "1" instead of "100" because the QUAD array elements would overflow for last few bits. To show as starting at "100" and times 2 for each, the "00" is appended to the output string build.
'This is console code. 'Console is easier for "one time quickie" than dialog, controls and callback. #compile exe #dim all ' function pbmain () as long local BitArray() as quad local BitNum as long local nSec, LPad as string dim BitArray(62) BitArray(0) = 1 for BitNum = 1 to 62 BitArray(BitNum) = BitArray(BitNum - 1) * 2 next for BitNum = 0 to 62 nSec = dec$(BitArray(BitNum, 19)) LPad = space$(20 - len(nSec)) con.print dec$(BitNum, 2) + LPad + nSec + "00" next con.waitkey$ end function 'Old syntax works, but "CON." differentiates this code from "TXT.". '(TXT.WINDOW does not scroll vertically, so is not suitable for this job.)
Created on 20 October 2024.
To
Domain Home.![]() | To Dale's Notebook index.![]() | To Programs index.![]() |