10

在回答之前,请仔细阅读这个问题。答案并不像看起来那么简单。

我正在编写一个程序,该程序需要跟踪文件的修改日期时间,其中一些文件存储在外部 FAT32 驱动器上。该程序正在各种 Windows 7 机器上运行。

问题是当前 UTC 偏移量发生变化时,UTC 修改的日期时间会发生变化。具体来说,当我们从新西兰标准时间 (UTC+12) 到新西兰夏令时间 (UTC+13) 再返回时。这不是错字 - UTC修改的日期时间更改。不应该,这是 UTC 的重点,但确实如此。这似乎是 FAT32 文件系统的限制 - NTFS 上的文件可以正常工作。

Console.WriteLine(DateTime.Now.ToString() + (DateTime.Now.IsDaylightSavingTime() ? " Daylight" : " Standard"));
Console.WriteLine(new FileInfo(args[0]).LastWriteTimeUtc.ToString("yyyyMMdd HH mmss"));

系统时区为新西兰,系统日期为新西兰标准时间 2012 年 4 月 9 日。

C:\Dev\UtcModifiedDatetime\bin\Debug>UtcModifiedDatetime.exe M:\Test1\Test.txt
2012-04-09 3:53:46 pm Standard
20120409 03 5316

现在将系统日期设置为 2012 年 3 月 1 日,即新西兰夏令时。请注意,我已重命名包含测试文件的目录。这很重要,因为否则Windows 将缓存文件的修改日期时间。在我弄清楚这一点之前,我浪费了很多时间。

C:\Dev\UtcModifiedDatetime\bin\Debug>UtcModifiedDatetime.exe M:\Test2\Test.txt
2012-03-01 3:54:13 pm Daylight
20120409 02 5316

现在将系统日期设置回 2012 年 4 月 9 日,并将时区更改为阿德莱德 (UTC+09:30)。

C:\Dev\UtcModifiedDatetime\bin\Debug>UtcModifiedDatetime.exe M:\Test3\Test.txt
2012-04-09 1:27:21 pm Standard
20120409 06 2316

那么我怎样才能得到正确的修改日期时间呢?我可以尝试确定该文件是否在 FAT32 文件系统上,如果是夏令时,请调整一小时,但即使我可以让它工作,这将是一个可怕的丑陋黑客。使用低级系统调用会起作用吗(我怀疑不是因为问题似乎出在操作系统级别)?我可以更改进程的时区,而不在整台机器上更改它吗?还有其他方法吗?

4

1 回答 1

11

问题是,FAT32 文件系统将文件时间存储为本地时间。因此 UTC 时间是计算的时间,它考虑了 DST,这会导致不同的 UTC 时间。一般来说,这个问题非常复杂,无法解决。

例如,您需要将真实的 UTC 文件修改时间存储在一个单独的文件中,在移除外部驱动器之前,必须在每台机器上同步该文件。如果同步至少不会执行一次,则不能认为它是正确的。并且没有简单的方法可以将其强制执行给用户。

于 2012-04-09T06:46:16.800 回答