无法从 FILETIME (Windows 时间)转换为 dateTime (我得到了不同的日期)
我读到的大多数文件在使用以下方法进行转换时都得到了正确的时间:
// 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 中浏览并查找该特定文件时,我会得到不同的日期!?这是我在查看文件属性时得到的日期:
为什么日期不匹配?我做错了什么?
Most of the files I read get the right time when using the following method to convert:
// 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);
}
Here I have an example in visual studio to show how this method sometimes does not work for example I will show the actual file in my computer and the debug. So the file that happens to be in my debug is:
"A:\Users\Tono\Documents\Visual Studio 2010\Projects\WpfApplication4\WpfApplication4\obj\x86\Debug\App.g.cs"
And here is the FILETIME that I am trying to convert to DateTime "I need the LastWriteTime by the way"
Here you can see that dwHighDateTime = 30136437 and also that dwLowDateTime = -2138979250 from that file.
And when I run my method plus other techniques I get the following dates:
So so far everything seems to be working great. But why is that that when I browse and look for that specific file in windows I get a different date !? Here is the date that I get when seeing the file's properties:
Why does the dates don't match? What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您需要按位而不是算术方式组合 LS 和 MS 值。
尝试:
或者以下任何一个也应该有效:
您可以通过加法而不是按位来逃脱,或者如果您确定这些值是正数(并且没有共同位)。但按位或可以更好地表达意图。
You need to combine the LS and MS values bitwise, not arithmetically.
Try:
Or any of the following should work too:
You can get away with adding rather than a bitwise-or if you are sure the values are positive (and have no bits in common). But bitwise-or expresses the intent better.
我参加聚会有点晚了,但这对我来说很可靠:
注意:不要相信 Windows 资源管理器。使用 File.GetLastWriteTimeUtc< /a> 方法,例如,根据此扩展方法返回的内容来验证文件系统实际具有的内容。资源管理器存在一些错误,在某些情况下不会更新文件时间。干杯! :)
注意:要测试这一点,您需要使用最大值。因此,假设 dwHighDateTime = dwLowDateTime = UInt32.MaxValue = 4294967295 = 0xFFFFFFFF,则可以得出
(long)(((ulong)UInt32.MaxValue << 32) + UInt32.MaxValue) = -1 = 0xFFFFFFFFFFFFFFFF。不幸的是,Windows API 中的谬误似乎是,最终需要将时间转换为 long 值,以便将其用于任何有用的应用程序(因为大多数 Windows API 方法都会占用文件时间)作为
和 dwLowDateTime = UInt32.MaxValue = 4294967295 = 0xFFFFFFFF,则得出long
值),这意味着一旦dwHighDateTime
上的前导位为高电平 (1
),该值就会变为负值。让我们尝试一下最大时间不要太长。假设 dwHighDateTime = Int32.MaxValue = 2147483647 = 0x7FFFFFFF(long)(((ulong)Int32 .MaxValue << 32) + UInt32.MaxValue) = 0x7FFFFFFFFFFFFFFF
。注意:
0x7FFFFFFFFFFFFFFF
已经比DateTime.MaxValue.ToFileTimeUtc() = 2650467743999999999 = 0x24C85A5ED1C04000
大得多,渲染这么大的数字对于任何实际应用来说已经毫无用处.NET 中的应用程序。I'm a bit late to the party, but this has worked reliably for me:
Note: Don't trust Windows Explorer. Use File.GetLastWriteTimeUtc method, for example, to verify what the file system actually has against what this extension method returns. Explorer has some bugs in it that don't update file times in certain situations. Cheers! :)
Note: To test this, you need to use maximum values. So, assuming
dwHighDateTime = dwLowDateTime = UInt32.MaxValue = 4294967295 = 0xFFFFFFFF
, it follows that(long)(((ulong)UInt32.MaxValue << 32) + UInt32.MaxValue) = -1 = 0xFFFFFFFFFFFFFFFF
. Unfortunately, the fallacy in the Windows API seems to be that eventually the time needs to be casted to along
value in order to work with it for any useful applications (since most Windows API methods take the file time as along
value), which means once the leading bit is high (1
) ondwHighDateTime
, the value becomes negative. Lets try with the maximum time not being high. AssumingdwHighDateTime = Int32.MaxValue = 2147483647 = 0x7FFFFFFF
anddwLowDateTime = UInt32.MaxValue = 4294967295 = 0xFFFFFFFF
, it follows that(long)(((ulong)Int32.MaxValue << 32) + UInt32.MaxValue) = 0x7FFFFFFFFFFFFFFF
.Note:
0x7FFFFFFFFFFFFFFF
is already much larger thanDateTime.MaxValue.ToFileTimeUtc() = 2650467743999999999 = 0x24C85A5ED1C04000
, rendering numbers that large already useless for any practical applications in .NET.这是我见过的另一种将 FileTime 结构转换为 long 的方法(使用结构中的编码运算符),然后可以使用 DateTime.FromFileTime 函数轻松将其转换为 DateTime:
This is another method that I have seen to convert a FileTime structure to a long (using a coded operator in the struct), which can then easily be converted to DateTime using the DateTime.FromFileTime functions:
我已经尝试过以下方法,但没有一个让我找到合适的时间:
我从 这里
I have tried the following and non of them get me the right time:
And I got the method from here
dwLowDateTime
和dwHighDateTime
应该是uint
,看起来它们是int
。更改此设置很可能会修复它,但正如 @Joe 指出的那样,您仍然应该使用|
而不是+
。dwLowDateTime
anddwHighDateTime
should beuint
and it looks like they areint
. Changing this will most likely fix it though as @Joe pointed out you should still use|
instead of+
.