14

私が読んだほとんどのファイルは、次の方法を使用して変換すると適切なタイミングで取得されます。

// 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);
}

ここでは、この方法が機能しない場合があることを示すためにVisual Studioの例を示します。たとえば、コンピューター内の実際のファイルとデバッグを示します。したがって、私のデバッグに含まれるファイルは次のとおりです。

"A:\ Users \ Tono \ Documents \ Visual Studio 2010 \ Projects \ WpfApplication4 \ WpfApplication4 \ obj \ x86 \ Debug \ App.g.cs" ここに画像の説明を入力してください

そして、これが私がDateTimeに変換しようとしているFILETIMEです「ちなみにLastWriteTimeが必要です」

ここに画像の説明を入力してください

ここでは、そのファイルからdwHighDateTime = 30136437であり、dwLowDateTime=-2138979250であることがわかります。

そして、メソッドと他のテクニックを実行すると、次の日付が表示されます。 ここに画像の説明を入力してください

これまでのところ、すべてがうまく機能しているようです。しかし、Windowsでその特定のファイルを参照して検索すると、別の日付が表示されるのはなぜですか?ファイルのプロパティを表示したときに取得する日付は次のとおりです。 ここに画像の説明を入力してください

日付が一致しないのはなぜですか?私は何が間違っているのですか?

4

5 に答える 5

19

LS値とMS値を、算術的にではなくビット単位で組み合わせる必要があります。

試す:

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

または、次のいずれかも機能するはずです。

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))

ビット単位ではなく追加することで回避できます。または、値が正であることが確実な場合(および共通のビットがない場合)。しかし、ビット単位で-または意図をより適切に表現します。

于 2011-05-21T19:03:57.407 に答える
9

私はパーティーに少し遅れていますが、これは私にとって確実に機能しました:

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);
        }
    }
}

:Windowsエクスプローラーを信頼しないでください。たとえば、 File.GetLastWriteTimeUtcメソッドを使用して、この拡張メソッドが返すものに対してファイルシステムが実際に持っているものを確認します。Explorerには、特定の状況でファイル時間を更新しないバグがいくつかあります。乾杯!:)

:これをテストするには、最大値を使用する必要があります。したがって、と仮定dwHighDateTime = dwLowDateTime = UInt32.MaxValue = 4294967295 = 0xFFFFFFFFすると、次のようになります(long)(((ulong)UInt32.MaxValue << 32) + UInt32.MaxValue) = -1 = 0xFFFFFFFFFFFFFFFF。残念ながら、Windows APIの誤謬は、long有用なアプリケーションで使用するために、最終的には時間を値にキャストする必要があることです(ほとんどのWindows APIメソッドはファイル時間をlong値として使用するため)。の先頭ビットがハイ(1dwHighDateTimeの場合、値は負になります。最大時間を高くしないで試してみましょう。と仮定するdwHighDateTime = Int32.MaxValue = 2147483647 = 0x7FFFFFFFdwLowDateTime = UInt32.MaxValue = 4294967295 = 0xFFFFFFFF、次のようになります(long)(((ulong)Int32.MaxValue << 32) + UInt32.MaxValue) = 0x7FFFFFFFFFFFFFFF

0x7FFFFFFFFFFFFFFFすでに。よりもはるかに大きいためDateTime.MaxValue.ToFileTimeUtc() = 2650467743999999999 = 0x24C85A5ED1C04000、.NETの実際のアプリケーションではすでに役に立たない数値になります。

于 2015-05-19T01:08:01.700 に答える
5

これは、FileTime構造体を(構造体でコード化された演算子を使用して)longに変換するために見た別のメソッドであり、DateTime.FromFileTime関数を使用して簡単にDateTimeに変換できます。

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;
    }
}
于 2012-06-19T22:32:56.770 に答える
0

dwLowDateTimeそしてそうdwHighDateTimeあるべきでuintあり、それは彼らがそうであるように見えますint。@Joeが指摘したように、これを変更すると修正される可能性が高くなりますが、.|の代わりに使用する必要があり+ます。

于 2011-05-21T19:23:48.317 に答える
0

私は次のことを試しましたが、どれも私に適切なタイミングを与えてくれませんでした:
ここに画像の説明を入力してください

そして、私はここからメソッドを取得しました

于 2011-05-21T19:46:00.003 に答える