C/C++

Convert FILETIME to Unix timestamp

Yes I know, C/C++ is not trendy these days. I don’t care.

So if you are trying to convert a FILETIME date that comes for example from the FindFirstFile/FindNextFile Win32 API you may find it’s not completely straightforward. Don’t try to accomplish this with some date function conversion because you will probably just waste a lot of time –I know because I did.

A UNIX timestamp contains the number of seconds from Jan 1, 1970, while the FILETIME documentation says: Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).

Between Jan 1, 1601 and Jan 1, 1970 there are 11644473600 seconds, so we will just subtract that value:

LONGLONG FileTime_to_POSIX(FILETIME ft)
{
	// takes the last modified date
	LARGE_INTEGER date, adjust;
	date.HighPart = ft.dwHighDateTime;
	date.LowPart = ft.dwLowDateTime;

	// 100-nanoseconds = milliseconds * 10000
	adjust.QuadPart = 11644473600000 * 10000;

	// removes the diff between 1970 and 1601
	date.QuadPart -= adjust.QuadPart;

	// converts back from 100-nanoseconds to seconds
	return date.QuadPart / 10000000;
}

And some code to show its usage (with various checks omitted for the sake of simplicity):

#include "stdafx.h"
#include "windows.h"

LONGLONG FileTime_to_POSIX(FILETIME ft);

int _tmain(int argc, _TCHAR* argv[])
{
	char d;
	WIN32_FIND_DATA FindFileData;
	HANDLE hFind;

	hFind = FindFirstFile(TEXT("C:\\test.txt"), &FindFileData);
	LONGLONG posix = FileTime_to_POSIX(FindFileData.ftLastWriteTime);
	FindClose(hFind);

	printf("UNIX timestamp: %ld\n", posix);
	scanf("%c", &d);

	return 0;
}