In .Net, how do I convert between SystemTime and FileTime?

2.1k Views Asked by At

As per https://msdn.microsoft.com/en-us/library/windows/desktop/ms724290(v=vs.85).aspx, a file time is a 64-bit value that represents the number of 100-nanosecond intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC).

To convert between SystemTime and FileTime, the Windows API functions SystemTimeToFileTime and FileTimeToSystemTime can be used.

I'm probably missing something here, because I don't think that this is a too rare task. However, searching SO for [.net] systemtimetofiletime provides as results just one (downvoted) answer and no relevant questions.

Perhaps it's just a lack of knowledge about the proper terminology, and SystemTimeToFileTime is called something very different in the .Net world.

Anyway, the question is, how do I properly convert between SystemTime and FileTime in .Net?

3

There are 3 best solutions below

2
On

Declare the PInvoke function and call it.

//Taken from http://www.codeproject.com/csharp/timezoneconversions.asp?print=true
private static DateTime SystemTimeToDateTime(ref SYSTEMTIME st)
{
        FILETIME ft = new FILETIME();
        SystemTimeToFileTime(ref st, out ft);
        DateTime dt = new DateTime((((long)ft.dwHighDateTime) << 32) | (uint)ft.dwLowDateTime);
        return dt;
}

Personally, I search the .NET Framework with a decompiler such as Reflector in such cases for existing usages. Often, Microsoft has already internally called the API that I need. Likely, their PInvoke code will be correct and ready to copy.

0
On

Seems like you're making it way too hard. In PowerShell, via .NET, you'd do it this way:

PS C:\Users\luser> ([System.DateTime]"Jan 05,2018").ToFileTime()
131596092000000000

PS C:\Users\luser> ([System.DateTime]::FromFileTime('131596092000000000'))

Friday, January 5, 2018 12:00:00 AM

System.Datetime has a CTOR that accepts just about any type of format you want to provide a datetime and then use the ToFileTime() method to get the int64 value.

Similarly, the Datetime class has a method for converting int64 values to DateTime using the FromFileTime() method.

or am I misunderstanding the problem?

0
On

I'm trying to convert FILETIME from upper and lower 32bit values found in the registry for when a user profile was last used in Windows 10 using PowerShell. Any ideas?

Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\SID\

LocalProfileUnloadTimeHigh = 30901163

LocalProfileUnloadTimeLow = 4255800258

[System.DateTime]::FromFileTime('425580025830901163')
    
Monday, August 11, 2949 7:23:03 AM

[System.DateTime]::FromFileTime('309011634255800258')
 
Tuesday, March 21, 2580 4:30:25 AM