Visual Studio 2015/2017 2038 年 ftime 函数错误

Visual Studio 2015/2017 Year 2038 bug with ftime functions

我正在将一些代码从 vc120 迁移到 vc140,我 运行遇到了 ftime64 的问题。该问题类似于 2015/2017 年 Visual Studio dev community where ftime64 seems to have a year-2038 bug 中提到的问题,但 2013 年没有。

下面是一些示例代码:

#include "stdafx.h"
#include <sys/timeb.h>
int main()
{
  __timeb64 testTime64;  
  _ftime64(&testTime64);  
  printf("%lld\n", testTime64.time);  
  return 0;
} 

日期在 03:14:07 UTC 2038/01/19 之后,时间似乎绕过了 32 位边界。

要进行测试,请将上述代码编译为 ftime_check 和 运行 以下来自管理命令提示符的代码(请注意,您的数字会因时钟上的时间而异):

date 1/18/2038 && ftime_check
2147474668
date 1/20/2038 && ftime_check
-2147319812

作为参考,这是在 vc120 下看到的(预期)输出:

date 1/18/2038 && ftime_check
2147482944
date 1/20/2038 && ftime_check
2147655752

我发现所有这些函数 ftime、_ftime、_ftime64、_ftime_s 和 _ftime64_s

都存在同样的问题

还有其他人遇到过这种情况吗?您是如何解决的?

在使用 Microsoft Visual Studio 支持打开问题后,他们已确认这是通用 CRT 的错误,可以通过使用更新的 Windows SDK 修复,该 SDK 计划与 Windows 10 Redstone 3(又名秋季创作者更新)。更新后的 UCRT 也将与 RS3 一起发布。

更新 2018/05/08:秋季创作者更新 (1709) 针对动态链接 CRT(/MD 和 /MDd)的应用程序修复了此问题。但是为了在针对 CRT(/MT 和 /MTd)进行静态链接时解决此问题,您必须将目标平台版本更改为 10.0.16299.0(或更高版本)并重建应用程序。

内部错误 ID 是:DevDiv.436129、437701

解决方法选项:
GetSystemTime(SYSTEMTIME *lpSystemTime)
SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, FILETIME *lpFileTime)

需要Windows 8或以上:
GetSystemTimePreciseAsFileTime(FILETIME *lpSystemTimeAsFileTime)

将 SYSTEMTIME 转换为 FILETIME
SYSTEMTIME 从 1601 年开始,而 time_t 通常从 1970 年开始。 要转换为 time_t,您必须考虑 1601 年和 1970 年之间的秒数差异(参见:Convert Windows Filetime to second in Unix/Linux