What is the safest way to subtract two System.Runtime.InteropServices.ComTypes.FILETIME objects
I wonder what is the safest way to subtract two System.Runtime.InteropServices.ComTypes.FILETIME
objects? I used the following code but sometimes it gives me ArithmaticOverflow exception due to the negative number in Low 32-bit values. I am not sure enclosing the b开发者_JS百科ody with unchecked
will serve the purpose or not. Please give me some suggestion on how to do it safely without getting any runtime exception or CS0675 warning message.
private static UInt64 SubtractTimes(FILETIME a, FILETIME b)
{
UInt64 aInt = ((UInt64)(a.dwHighDateTime << 32)) | (UInt32)a.dwLowDateTime;
UInt64 bInt = ((UInt64)(b.dwHighDateTime << 32)) | (UInt32)b.dwLowDateTime;
return aInt - bInt;
}
You need to use unchecked to suppress the exception:
public static long FileTime2Long(FILETIME ft) {
uint low = unchecked((uint)ft.dwLowDateTime);
return (long)ft.dwHighDateTime << 32 | low;
}
static void Test() {
FILETIME ft = new FILETIME();
ft.dwHighDateTime = 1;
ft.dwLowDateTime = -1;
long value = FileTime2Long(ft);
Debug.Assert(value == 0x1ffffffff);
}
If desired, you can then convert to DateTime with DateTime.FromFileTimeUtc().
You can convert FILETIME to DateTime object by using DateTime.FromFileTime() method and then you can safely substract DateTime objects.
If you will have a same problem then use method below because DateTime.FromFileTime() doesn't work in all cases thanks to signed/unsigned issues.
public static DateTime ToDateTime( System.Runtime.InteropServices.FILETIME ft )
{
IntPtr buf = IntPtr.Zero;
try
{
long[] longArray = new long[1];
int cb = Marshal.SizeOf( ft );
buf = Marshal.AllocHGlobal( cb );
Marshal.StructureToPtr( ft, buf, false );
Marshal.Copy( buf, longArray, 0, 1 );
return DateTime.FromFileTime( longArray[0] );
}
finally
{
if ( buf != IntPtr.Zero ) Marshal.FreeHGlobal( buf );
}
}
精彩评论