Archive: GetFileTime


GetFileTime
i'm trying to convert the time returned from GetFileTime into seconds.

forget doing it with code for now, we can come back to that after, first help me do it manually, my result is wrong...

working:

timestamp returned from the file i'm working on is:
29851110, -1418797106

1) -1418797106 is not the true decimal representation of the second half because bit 32 was taken as a negative in twos's compliment! to get the real positive value from the negative value...

lowest part of the range for a 32bit 2's compliment number = -2147483648

so whats the difference between that and our number? because that will give us the true decimal representation of its 1 to 31.
-2147483648 - -1418797106 = 2147483648 - 1418797106 = 728686542

now take the 32nd bit as a positive value = 2147483648

now add bits 32 and 1->31 together: 2147483648 + 728686542 = 2876170190

so the true decimal value for the second half is:
*****************
2876170190
*****************

2) 29851110 is not the true representation of the first half because the wrong unit column headings were used to convert it to decimal. so to get the true value we do what?

if we have 111 (7 base10), pretend those represent bits 9,10,11 in a larger binary number (i.e. columns 256, 512, 1024), it's really 1792 base10.
1792 / 7 = 256, so we see that we could have just multiplied the value by the value of the first true unit column: 7 * 256 = 1792.

so 29851110 * 4294967296 =
*******************
128209541199298560
*******************

3) now, if we add #2 (decimal of bits 33-64) and #1 (decimal of bits 1-32) together we get:

128209541199298560 + 2876170190 =
###################
128209544075468750
###################

4) now, this value 128209544075468750 should represent:

"the number of 100 nanosecond intervals since the unix epoch"

to convert to seconds apparently we divide by 10,000,000

128209544075468750 / 10000000 =
####################
12820954407.5468750
####################
BUT that cannot be correct!!!

using the date() and mktime() functions in PHP with the last modified date of that file (13 April 2007, 17:13:27), i get 1178400480

PHP is giving me a ten digit number beginning 117
this is giving me an eleven digit number beginning 128

so what the hell am i doing wrong........... :mad:

4.9.3.7 GetFileTime
filename user_var(high dword output) user_var(low dword output)
Gets the last write time of "filename". ...
it does not retrieve the current time like mktime().



for general help about how to convert the file time values see:
http://msdn2.microsoft.com/en-us/library/ms724284.aspx

although you seemed to have completely misunderstood what i wrote about PHP, your link did provide a vital clue: PHP measures from 1970 while Windows measures from 1601, a difference of 369 years :D

just to briefly explain what i did in PHP for you: i took the last modified time (13 April 2007, 17:13:27), put that in mktime() to generate a timestamp for it, and then put that into date() to output it as a unix timestamp (seconds since the unix epoch - well the one PHP uses anyway lol).

factoring the 369 year difference into the PHP timestamp i then get an eleven digit number beginning 128 as i did with my calculations so all is well :)

now to do some code, and the link really helps for that :)

thanks


alright :)

i'd appreciate, if you have a hint for me how to convert the FILETIME values into a valid timestamp, so i can use it with strftime() (in c code).


well...

the basic instructions to convert to a readable decimal number in seconds:
1) either treat the lower dword as an unsigned number (you can do this with intfmt $0 "%u" in NSIS), or otherwise manually: if negative, firstly get the difference between it and -2147483648, then add 728686542.
2) for the higher dword, multiply it by 4294967296.
3) now add them together and you get the true decimal number
4) then you can divide by 10000000 to convert to seconds

of course it seems a much easier way to do this in code is to simply use some sort of system::int64 call but thats something i haven't looked into yet.

the problem i'm facing myself at the moment is that the info in the link you gave me suggests that on a windows system using NTFS the timestamp is based on the UTC+0 timezone, however on a system using FAT, the timezone the user selects for their system clock is used, which means you probably can't compare them.
it may be that somehow i need to do a system call to get the filesystem type (NTFS/FAT), if FAT then do some system call to get the timezone offset from UTC+0, and then get the timestamp and convert to UTC+0, then i can use it for a comparison. however all of this may be too complex a solution for what i need to use it for, and that may not be accurate anyway.

you should also read the wikipedia article on epoch's because some other software including some of microsofts own use a different epoch (reference point in time from which a measurement in time is taken) to windows itself so that could be another problem with comparing timestamps.


Will an MD5 checksum comparison not do?

Stu


you mean as a solution for the problem i was doing this for? if so then no, hashes definitely won't do. however i do now have a far more simple solution than timestamps and hashes up my sleeve which may work instead :)