not being able to convert from FILETIME (windows time) to dateTime ( I get a different date )

Tono Nam picture Tono Nam · May 21, 2011 · Viewed 12k times · Source

Most of the files I read get the right time when using the following method to convert:

// works great most of the time
private static DateTime convertToDateTime(System.Runtime.InteropServices.ComTypes.FILETIME time)
{
    long highBits = time.dwHighDateTime;
    highBits = highBits << 32;
    return DateTime.FromFileTimeUtc(highBits + time.dwLowDateTime);
}

Here I have an example in visual studio to show how this method sometimes does not work for example I will show the actual file in my computer and the debug. So the file that happens to be in my debug is:

"A:\Users\Tono\Documents\Visual Studio 2010\Projects\WpfApplication4\WpfApplication4\obj\x86\Debug\App.g.cs" enter image description here

And here is the FILETIME that I am trying to convert to DateTime "I need the LastWriteTime by the way"

enter image description here

Here you can see that dwHighDateTime = 30136437 and also that dwLowDateTime = -2138979250 from that file.

And when I run my method plus other techniques I get the following dates: enter image description here

So so far everything seems to be working great. But why is that that when I browse and look for that specific file in windows I get a different date !? Here is the date that I get when seeing the file's properties: enter image description here

Why does the dates don't match? What am I doing wrong?

Answer

Joe picture Joe · May 21, 2011

You need to combine the LS and MS values bitwise, not arithmetically.

Try:

        ulong high = 30136437;
        unchecked
        {
            int low = -2138979250;
            uint uLow = (uint)low;
            high = high << 32;
            Date dt = DateTime.FromFileTime((long) (high | (ulong)uLow));
        }

Or any of the following should work too:

long highBits = time.dwHighDateTime;     
highBits = highBits << 32;     

return DateTime.FromFileTimeUtc(highBits + (long) (uint) time.dwLowDateTime); 

return DateTime.FromFileTimeUtc(highBits | (long) (uint) time.dwLowDateTime); 

return DateTime.FromFileTimeUtc(highBits + ((long)low & 0xFFFFFFFF))

return DateTime.FromFileTimeUtc(highBits | ((long)low & 0xFFFFFFFF))

You can get away with adding rather than a bitwise-or if you are sure the values are positive (and have no bits in common). But bitwise-or expresses the intent better.