我正在开发一个程序,用于记录文件中的日期元数据,例如创建时间、上次修改时间等。该程序的旧版本是用 VBA 编写的,并执行以下操作:
Public Function GetFileLastAccessTime(ByVal FilePath As String) As Date
Dim fso As New Scripting.FileSystemObject
Dim f As Scripting.File
Set f = fso.GetFile(FilePath)
GetFileLastAccessTime = f.DateLastAccessed
End Function
相关文件的输出:
?getfilelastaccesstime("SomePath")
7/30/2010 2:16:07 PM
这是我从 Windows Exploder 中的文件属性中获得的值。幸福。
我正在将此功能移植到 VB.Net 应用程序。新代码:
Public Function GetLastAccessTime(ByVal FilePath As String) As Date
Return IO.File.GetLastAccessTime(FilePath)
End Function
简单本身。输出:
?GetLastAccessTime("SomePath")
#7/30/2010 3:16:07 PM#
一小时后。
这两个函数都在同一台机器上运行,检查相同的文件。我还尝试使用 IO.FileInfo 类获得相同的结果。我检查了数千个文件,它们都晚了一小时。创建时间和上次修改时间的其他日期属性也相差一小时。
Help!
我忘了在原来的帖子中提到,计算机的时区是 CST,夏令时目前尚未生效。
我在 Windows 7 64 位和 Windows XP 32 位上重现了该问题。
Thanks.
2011 年 1 月 6 日更新:
感谢所有建议尝试使用适当的时区偏移量从 UTC 计算所需日期的人。此时我决定不值得冒险这样做。对于这个特定的业务需求,最好说日期值不是您期望的那样,因为这就是 API 的工作方式。如果我试图“修复”这个问题,那么我就拥有它,但我宁愿不这样做。
只是为了好玩,我尝试通过互操作使用旧的 Scripting.FileSystemObject。它给出的预期结果与 Windows 资源管理器一致,但与 System.IO 相比,性能损失大约为 5 倍。如果事实证明我必须获得与 Windows 资源管理器相匹配的日期,我会硬着头皮走这条路。
我尝试的另一个实验是通过 C# 直接访问 kernel32 中的 GetFileTime API 函数:
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GetFileTime(
IntPtr hFile,
ref FILETIME lpCreationTime,
ref FILETIME lpLastAccessTime,
ref FILETIME lpLastWriteTime
);
这导致了与 System.IO 完全相同的行为,时间比 Windows 资源管理器晚了一个小时。
再次感谢大家。