C# 无法从FILETIME(windows时间)转换为dateTime(我得到了不同的日期)

C# 无法从FILETIME(windows时间)转换为dateTime(我得到了不同的日期),c#,datetime,datetime-format,filetime,C#,Datetime,Datetime Format,Filetime,使用以下方法转换时,我读取的大多数文件都会在正确的时间进行转换: // works great most of the time private static DateTime convertToDateTime(System.Runtime.InteropServices.ComTypes.FILETIME time) { long highBits = time.dwHighDateTime; highBits = highBits << 32; retu

使用以下方法转换时,我读取的大多数文件都会在正确的时间进行转换:

// 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);
}
//在大多数情况下效果都很好
专用静态DateTime convertToDateTime(System.Runtime.InteropServices.ComTypes.FILETIME)
{
长高位=time.dwHighDateTime;

highBits=highBits您需要按位组合LS和MS值,而不是按算术组合

尝试:

ulong高=30136437;
未经检查
{
整数低位=-2138979250;
uint uLow=(uint)低;

high=high
dwLowDateTime
dwHighDateTime
应该是
uint
,看起来它们是
int
。更改此选项很可能会解决此问题,尽管@Joe指出,您仍然应该使用
而不是
+

我已经尝试了以下方法,但它们中的任何一个都没有找到正确的时间:r>


我从

中得到了这个方法,这是我见过的另一个将FileTime结构转换为long(使用结构中的编码运算符)的方法,然后可以使用DateTime轻松地将其转换为DateTime。FromFileTime函数:

public struct FileTime
{
    public uint dwLowDateTime;
    public uint dwHighDateTime;

    public static implicit operator long(FileTime fileTime)
    {
        long returnedLong;
        // Convert 4 high-order bytes to a byte array
        byte[] highBytes = BitConverter.GetBytes(fileTime.dwHighDateTime);
        // Resize the array to 8 bytes (for a Long)
        Array.Resize(ref highBytes, 8);

        // Assign high-order bytes to first 4 bytes of Long
        returnedLong = BitConverter.ToInt64(highBytes, 0);
        // Shift high-order bytes into position
        returnedLong = returnedLong << 32;
        // Or with low-order bytes
        returnedLong = returnedLong | fileTime.dwLowDateTime;
        // Return long 
        return returnedLong;
    }
}
public struct FileTime
{
公共uint dwLowDateTime;
公共单位时间;
公共静态隐式运算符long(FileTime FileTime)
{
长返回长;
//将4个高阶字节转换为字节数组
byte[]highBytes=BitConverter.GetBytes(fileTime.dwHighDateTime);
//将数组大小调整为8字节(长时间)
调整数组大小(参考高字节,8);
//将高阶字节分配给长字符串的前4个字节
returnedLong=BitConverter.ToInt64(高字节,0);
//将高位字节移位到位

returnedLong=returnedLong我参加聚会有点晚了,但这对我来说确实有效:

public static class FILETIMEExtensions
{
    public static DateTime ToDateTime(this System.Runtime.InteropServices.ComTypes.FILETIME time)
    {
        ulong high = (ulong)time.dwHighDateTime;
        uint low = (uint)time.dwLowDateTime;
        long fileTime = (long)((high << 32) + low);
        try
        {
            return DateTime.FromFileTimeUtc(fileTime);
        }
        catch
        {
            return DateTime.FromFileTimeUtc(0xFFFFFFFF);
        }
    }
}
公共静态类FILETIMEExtensions
{
公共静态日期时间ToDateTime(此System.Runtime.InteropServices.ComTypes.FILETIME)
{
ulong high=(ulong)time.dwHighDateTime;
uint low=(uint)time.dwLowDateTime;

long fileTime=(long)(high)为什么要这么做?看起来你几乎在重写FileInfo类…我不知道OP为什么要这么做。当使用长路径名时,这是比[MAX_LENGTH]长的路径=260字节,您将需要重写System.IO的大部分以使用非托管代码。此处有更多信息:使用FILETIME/GetFileTime而不是FileInfo有合法的场景:例如,如果您想获取已打开句柄的文件的统计信息(由于某些原因无法通过FileInfo重新打开该文件)time.dwLowDateTime显示为负值(不应该为负值),因此将其转换为long将给出错误的结果。相反,IIRC需要执行
(long)((uint)(time.dwLowDateTime))
或修复互操作,使其以uint开始。我认为我的方法是读取错误日期的方法。我将继续尝试找出它。您是否都找到了修复方法?此解决方案对我有效,而其他答案返回错误results@DavidRoberts那是因为其他答案不包括在内在high date time组件中,将其转换为无符号的64位值…相反,我发现它们错误地转换为有符号的64位值,这可能会返回一个不正确的负结果。事实上,这似乎是最准确的解决方案。
public struct FileTime
{
    public uint dwLowDateTime;
    public uint dwHighDateTime;

    public static implicit operator long(FileTime fileTime)
    {
        long returnedLong;
        // Convert 4 high-order bytes to a byte array
        byte[] highBytes = BitConverter.GetBytes(fileTime.dwHighDateTime);
        // Resize the array to 8 bytes (for a Long)
        Array.Resize(ref highBytes, 8);

        // Assign high-order bytes to first 4 bytes of Long
        returnedLong = BitConverter.ToInt64(highBytes, 0);
        // Shift high-order bytes into position
        returnedLong = returnedLong << 32;
        // Or with low-order bytes
        returnedLong = returnedLong | fileTime.dwLowDateTime;
        // Return long 
        return returnedLong;
    }
}
public static class FILETIMEExtensions
{
    public static DateTime ToDateTime(this System.Runtime.InteropServices.ComTypes.FILETIME time)
    {
        ulong high = (ulong)time.dwHighDateTime;
        uint low = (uint)time.dwLowDateTime;
        long fileTime = (long)((high << 32) + low);
        try
        {
            return DateTime.FromFileTimeUtc(fileTime);
        }
        catch
        {
            return DateTime.FromFileTimeUtc(0xFFFFFFFF);
        }
    }
}