IO.File.GetLastAccessTime 关闭一小时

2024-02-06

我正在开发一个程序,用于记录文件中的日期元数据,例如创建时间、上次修改时间等。该程序的旧版本是用 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 资源管理器晚了一个小时。

再次感谢大家。


我可以在 XP/Win2k3/Vista 上使用 .NET 4.0 和 2.0/3.5 重现这一点。

问题是 DST 与现在处于不同的状态,并且 .NET 处理这种差异的方式与 Explorer 和Scripting.FileSystemObject.

(当 DST 与压缩文件时不同时,从 zip 文件中提取文件时,您会遇到类似的问题。)

通过 Reflector,.NET 与非 .NET 代码路径不同的原因是,所有三个本地日期戳IO.File (and IO.FileInfo) 的实现方式是获取 Utc 日期戳并应用.ToLocalTime,它根据本地时区是否发生 DST 来确定要添加的偏移量UTC 时间.

我还检查了,通过将日期更改为去年 7 月 1 日,创建一个文件并在返回当前日期(3 月 16 日)时查看时间戳(我在南澳大利亚,所以我们现在处于 DST,而不是7 月 1 日)和 Windows(大概是FileSystemObject) 添加夏令时NOW所以显示的时间实际上发生了变化。

所以,综上所述,.NET 更为正确。

但如果您想要不正确但与资源管理器相同的日期,请使用:

Public Function GetLastAccessTime(ByVal FilePath As String) As Date
    Return IO.File.GetLastAccessTimeUtc(FilePath) _
      .Add(TimeZone.CurrentTimeZone.GetUtcOffset(Now))
End Function 

这已经讨论过雷蒙德·陈的博客 http://blogs.msdn.com/b/oldnewthing/archive/2003/10/24/55413.aspx(总结是:.NET 直观上是正确的,但并不总是可逆的,而 Win32 是严格正确的且可逆的)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IO.File.GetLastAccessTime 关闭一小时 的相关文章

  • OpenArgs 为空问题

    我正在使用OpenArgs使用时发送值的参数DoCmd OpenForm DoCmd OpenForm frmSetOther acNormal acFormAdd acDialog value 然后我用Me OpenArgs在打开的表格内
  • MS Access 执行 POST Web 请求

    在我的 MS Access 应用程序中 我需要定期向我的网络服务器发送一批信息 我不需要任何花哨的东西 比如 SOAP XML RPC 或任何东西 只需一个简单的 POST 页面请求就足够了 我用谷歌搜索了一下 但找不到任何真正有用的东西
  • 这个 SQL 查询有什么问题?

    在过去的一个小时里 我一直在尝试此查询的不同变体 但我在用户名处收到错误 并且用户名只是一个普通字符串 其中的用户名是我从不包含特殊字符或任何内容的 xml 文件中获取的 我正在使用 SLQ 紧凑型 3 5 P S 我尝试使用 而不是 us
  • 在 VBA 中循环合并单元格

    是否可以循环遍历合并的单元格vba questions tagged vba 我的范围内有 6 个合并单元格B4 B40 我只需要这 6 个单元格中的值 6 次迭代 上面的答案看起来已经让你排序了 如果您不知道合并的单元格在哪里 那么您可以
  • 如何在.NET中使用java.util.zip.Deflater解压缩放气流?

    之后我有一个转储java util zip Deflater 可以确认它是有效的 因为 Java 的Inflater打开它很好 并且需要在 NET中打开它 byte content ReadSample sampleName var inp
  • 如何在 SqlDataReader.Read() 期间从死锁异常中恢复

    我的 NET 应用程序的事件日志显示 它在从 Sql Server 读取数据时偶尔会出现死锁 这种情况通常非常罕见 因为我们已经优化了查询以避免死锁 但有时仍然会发生 过去 我们在调用ExecuteReader函数在我们的SqlComman
  • 字典、集合和数组的比较

    我正在尝试找出字典与集合和数组相比的相对优点和功能 我发现了一篇很棒的文章here http www experts exchange com articles 3391 Using the Dictionary Class in VBA
  • VBA根据单元格的值是否为零显示/隐藏行

    我有一个 Excel 工作表 我想根据另一个单元格中的值隐藏或取消隐藏某些行 简而言之 整个事情应该取决于单元格中的值C2 D2 E2 If C2 is blank我想rows 31 to 40被隐藏 如果是的话不为空 他们需要是visib
  • 根据所选单选按钮启用文本框

    我有一个单选按钮列表 其中列出了不同的业务类别 最后一个选项是Other类别 当用户选择Other类别 我希望能够启用一个文本框 用户可以输入更多信息来解释Other选择 目前 我正在尝试 If rblCategory SelectedIn
  • 终结器线程的范围是什么 - 每个应用程序域或每个进程?

    根据我的所有阅读 应该有一个 GC 线程来调用所有终结器 现在的问题是这个 一个 线程的范围是什么 每个进程或每个应用程序域 因为域的整体目的是在一个进程空间中分离并创建 独立 的不同应用程序 I read here http dn cod
  • 如何禁用 Alt + F4 关闭表单?

    What is the best way to disable Alt F4 in a c win form to prevent the user from closing the form 我使用表单作为弹出对话框来显示进度条 但我不希
  • 如何在 C# 中向类、方法、属性等添加文档工具提示?

    不确定我的说法是否正确 但我想开始向我的类 方法 属性等添加一些文档 我know这可能是非常明显的 但我从未真正学会过 我不知道从哪里开始 只是为了澄清 每当您滚动某个类 或方法 属性等 时 它都会在 Visual Studio 中显示一个
  • WCF WebHttp 混合身份验证(基本和匿名)

    所有这些都与 WebHttp 绑定有关 托管在自定义服务主机中 IIS 目前不是一个选项 我已经实现了自定义 UserNamePasswordValidator 和自定义 IAuthorizationPolicy 当我将端点的绑定配置为使用
  • Nullable 是不可能的,为什么不呢? [复制]

    这个问题在这里已经有答案了 如果这是一个愚蠢的问题 请原谅 我正在尝试更好地理解 Net 中的 Nullable 类型 从我从 Microsoft 源代码 使用 ReSharper 中注意到的内容 我了解到 Nullable 是一个结构 而
  • PrivateObject 找不到属性

    我的结构基本上如下所示 abstract class A protected string Identificator get set private void DoSomething DoSomethingSpecific protect
  • 我需要安装什么才能获取 Microsoft.TeamFoundation.WorkItemTracking.Client.dll?

    我只需要安装VS2010 SDK http www microsoft com downloads en details aspx FamilyID 47305cf4 2bea 43c0 91cd 1b853602dcc5 是否有 TFS2
  • MSChart 控件中的自定义 X/Y 网格线

    我有一个带有简单 2D 折线图的 C Windows 窗体 我想向其中添加自定义 X 或 Y 轴标记 并绘制自定义网格线 例如 以突出显示的颜色 虚线 我查看了 customLabels 属性 但这似乎覆盖了我仍然想显示的默认网格 这是为了
  • 将 dll 注册到 GAC 或从 ASP.NET 中的 bin 文件夹引用它们是否更好

    如果答案是 视情况而定 您能否提供一个简短的解释 GAC 旨在包含以下组件跨多个应用程序共享 如果是这种情况 您应该对程序集进行强命名并向 GAC 注册 如果不是 请将程序集保留为私有程序集并将其作为项目 dll 引用进行引用 PS 没有真
  • 将日期时间显示为 MM/dd/yyyy HH:mm 格式 C#

    在数据库中 日期时间以 MM dd yyyy HH mm ss 格式存储 但是 我想以 MM dd yyyy HH mm 格式显示日期时间 我通过使用 String Format 进行了尝试 txtCampaignStartDate Tex
  • 使用 IdentityDbContext 和 Code First 自动迁移表位置和架构的实体框架?

    我正在尝试使用 IdentityDbContext 类设置自动迁移更新 并将更改传播到整个数据库的实际 DbContext 在进入代码之前 在使用自动迁移实现 IdentityDbContext 时 我收到此错误 影响迁移历史系统表位置的自

随机推荐