使用stat API获取不正确的文件修改时间

时间:2015-08-31 18:07:30

标签: c++ c windows winapi

我在获取文件的修改时间时看到一种奇怪的行为。 我们一直在调用_stat64方法来获取项目中的文件修改,如下所示。

int my_win_stat( const char *path, struct _stati64 *buf)
{  
 if(_stati64( path, buf) == 0)
 {
   std::cout<<buf->st_mtime << std::endl; //I added to ensure if value is not changing elsewhere in the function.
 }
 ...........
 ...........
}

当我使用epoch convertor转换st_mtime变量返回的纪元时间时,它显示在我系统上设置的当前时间之前2:30。

当我从不同的测试项目中调用相同的API时,我看到了正确的mtime(即根据我系统显示的文件的mtime)。

if (_stat64("D:\\engine_cost.frm", &buffer) == 0)
    std::cout << buffer.st_mtime << std::endl;

即使我在GetFileTime()帖子的帮助下调用this并将FILETIME转换为纪元时间。我根据设置系统的时间得到正确的时间。

if (GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite))
{
    ULARGE_INTEGER ull;
    ull.LowPart = ftWrite.dwLowDateTime;
    ull.HighPart = ftWrite.dwHighDateTime;

    std::cout << (ull.QuadPart / 10000000ULL - 11644473600ULL);
}

我无法弄清楚为什么通过现有项目调用mtime的时间不同?
有什么参数可能影响mtime的输出?
还有什么我可以尝试进一步调试问题?

注意

  1. 在VS2013中,_stati64是一个替换为_stat64的宏。
  2. 文件系统是Windows 7上的NTFS。

2 个答案:

答案 0 :(得分:1)

Unix时间真的很容易处理。它是自1970年1月1日以来的秒数(即0表示特定日期)。

现在,您所说的是您正在使用浏览器中的第三方工具测试您的时间(mtime),并期望能够为您提供正确的答案。所以...让我们做一个测试,以下号码是2015年9月1日格林尼治标准时间00:00:00。

1441065600

如果您使用Epoch Converter并使用它非常有价值,它会为您提供正确的GMT吗? (如果不是,那么事情确实是错误的。)然后查看当地时间价值,看看你是否得到了GMT午夜的预期。 (请注意,我使用GMT,因为Epoch Converter使用该缩写,但正确的缩写是UTC。)

在我看来,您的代码很可能会提取正确的时间,但是epoch转换器会在您的计算机上失效并在当地时间。

请注意,您可以使用以下内容在C ++程序中进行测试:

std::cerr << ctime(&buf->st_mtime) << std::endl;

(注意,因为ctime()不是线程安全的)

这将在运行时根据您的计算机上的区域设置为您提供数据。

要更好地控制日期格式,请使用strftime()。该函数使用tm结构,因此您必须先调用gmtimelocaltime

答案 1 :(得分:0)

一年后,我遇到了类似的问题,但情况略有不同。但是这次我理解为什么会有+2:30小时的差距。我通过perl脚本执行C ++程序,实习生设置时区'GMT-3',我的机器已经在时区'GMT + 5:30'。结果是'2:30Hrs'的差异。 为什么?正如哈利在this post

中提到的那样
  

更改Perl中的时区可能导致设置TZ环境变量,这会影响C运行时库as per the documentation for _tzset