I am migrating some code from vc120 to vc140 and I am running into a problem with ftime64. The problem is similar to one mentioned on the Visual Studio dev community where ftime64 seems to have a year-2038 bug in 2015/2017 but where 2013 does not.
Here's some example code:
#include "stdafx.h"
#include <sys/timeb.h>
int main()
{
__timeb64 testTime64;
_ftime64(&testTime64);
printf("%lld\n", testTime64.time);
return 0;
}
With dates after 03:14:07 UTC on 2038/01/19, the time appears to wrap over the 32-bit boundary.
To test, compile the above code as ftime_check and run the following from an admin command prompt (note your numbers will vary due to the time of day on your clock):
date 1/18/2038 && ftime_check
2147474668
date 1/20/2038 && ftime_check
-2147319812
For reference, here is the (expected) output as seen under vc120:
date 1/18/2038 && ftime_check
2147482944
date 1/20/2038 && ftime_check
2147655752
I see the same issue with all of these functions ftime, _ftime, _ftime64, _ftime_s, and _ftime64_s
Is anyone else experiencing this, and how are you working around it?
After opening an issue with Microsoft Visual Studio support, they have confirmed this as a bug with Universal CRT that can be fixed by using an updated Windows SDK that is slated to release alongside Windows 10 Redstone 3 (aka Fall Creators Update). An updated UCRT will also be released alongside RS3.
Update 2018/05/08: The Fall Creator's Update (1709) fixed this for applications linking dynamically against the CRT (/MD and /MDd). But in order to fix this when linking statically against the CRT (/MT and /MTd), you must change the Target Platform Version to 10.0.16299.0 (or later) and rebuild the application.
The internal bug ID is: DevDiv.436129 , 437701
Workaround options:
GetSystemTime(SYSTEMTIME *lpSystemTime)
SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, FILETIME *lpFileTime)
Requires Windows 8 or above:
GetSystemTimePreciseAsFileTime(FILETIME *lpSystemTimeAsFileTime)
Convert SYSTEMTIME to FILETIME
SYSTEMTIME starts in year 1601 while time_t usually starts in year 1970.
To convert to time_t you have to account for the difference in seconds between 1601 and 1970 (See: Convert Windows Filetime to second in Unix/Linux)