Reputation:
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?
Upvotes: 0
Views: 2452
Reputation: 11
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
Upvotes: 0
Reputation: 2935
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?
Upvotes: 0
Reputation: 171188
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.
Upvotes: 2