Convert Windows Filetime to second in Unix/Linux
it's quite simple: the windows epoch starts 1601-01-01T00:00:00Z. It's 11644473600 seconds before the UNIX/Linux epoch (1970-01-01T00:00:00Z). The Windows ticks are in 100 nanoseconds. Thus, a function to get seconds from the UNIX epoch will be as follows:
#define WINDOWS_TICK 10000000
#define SEC_TO_UNIX_EPOCH 11644473600LL
unsigned WindowsTickToUnixSeconds(long long windowsTicks)
{
return (unsigned)(windowsTicks / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
}
Convert Unix/Linux time to Windows FILETIME
The Microsoft documentation for the FILETIME
structure explains what it is. The basic idea is that a Windows FILETIME
counts by steps of 10-7 seconds (100-nanosecond intervals) from 1 Jan 1601 (why 1601? no idea...). In Linux you can obtain time in microseconds (10-6) from 1 Jan 1970 using gettimeofday()
. Thus the following C function does the job:
#include <sys/time.h>
/**
* number of seconds from 1 Jan. 1601 00:00 to 1 Jan 1970 00:00 UTC
*/
#define EPOCH_DIFF 11644473600LL
unsigned long long
getfiletime() {
struct timeval tv;
unsigned long long result = EPOCH_DIFF;
gettimeofday(&tv, NULL);
result += tv.tv_sec;
result *= 10000000LL;
result += tv.tv_usec * 10;
return result;
}
Convert current time from windows to unix timestamp in C or C++
Maybe my question was phrased badly: All I wanted was to get the current time on a windows machine as a unix timestamp.
I now figured it out myself (C language, Code::Blocks 12.11, Windows 7 64 bit):
#include <stdio.h>
#include <time.h>
int main(int argc, char** argv) {
time_t ltime;
time(<ime);
printf("Current local time as unix timestamp: %li\n", ltime);
struct tm* timeinfo = gmtime(<ime); /* Convert to UTC */
ltime = mktime(timeinfo); /* Store as unix timestamp */
printf("Current UTC time as unix timestamp: %li\n", ltime);
return 0;
}
Example output:
Current local time as unix timestamp: 1386334692
Current UTC time as unix timestamp: 1386331092
Converting time from one environment into another in C++
Here is code to do this which was actually donated to this site by a member of the MSVC std::lib team (Billy O'Neal).
Repeated here:
// filetime_duration has the same layout as FILETIME; 100ns intervals
using filetime_duration = duration<int64_t, ratio<1, 10'000'000>>;
// January 1, 1601 (NT epoch) - January 1, 1970 (Unix epoch):
constexpr duration<int64_t> nt_to_unix_epoch{INT64_C(-11644473600)};
system_clock::time_point
FILETIME_to_system_clock(FILETIME fileTime)
{
const filetime_duration asDuration{static_cast<int64_t>(
(static_cast<uint64_t>(fileTime.dwHighDateTime) << 32)
| fileTime.dwLowDateTime)};
const auto withUnixEpoch = asDuration + nt_to_unix_epoch;
return system_clock::time_point{
duration_cast<system_clock::duration>(withUnixEpoch)};
}
This converts to system_clock::time_point
, which has nanoseconds precision on Linux and 100-nanosecond precision on Windows.
Using my date/time library, it is easy to format system_clock::time_point
to full precision with any format you want.
Also, here it is without using the Windows FILETIME
structure:
#include "date.h"
#include <string>
#include <iostream>
std::chrono::system_clock::time_point
FILETIME_to_system_clock(std::uint64_t fileTime)
{
using namespace std;
using namespace std::chrono;
// filetime_duration has the same layout as FILETIME; 100ns intervals
using filetime_duration =duration<int64_t, ratio<1, 10000000>>;
// January 1, 1601 (NT epoch) - January 1, 1970 (Unix epoch):
constexpr duration<int64_t> nt_to_unix_epoch{INT64_C(-11644473600)};
const filetime_duration asDuration{static_cast<int64_t>(fileTime)};
const auto withUnixEpoch = asDuration + nt_to_unix_epoch;
return system_clock::time_point{
duration_cast<system_clock::duration>(withUnixEpoch)};
}
int
main()
{
std::string s = date::format("%F %T", FILETIME_to_system_clock(131400356659154460));
std::cout << s << '\n';
}
This just output for me:
2017-05-23 17:54:25.915446
Note that this is only to microseconds precision. On Linux, this will format to nanoseconds precision because system_clock::time_point
has nanoseconds precision on that platform.
If that weren't the case, you could force nanosecond-precision like this:
using namespace std::chrono;
std::string s = date::format("%F %T",
time_point_cast<nanoseconds>(FILETIME_to_system_clock(131400356659154460)));
Output for me:
2017-05-23 17:54:25.915446000
In this update the precision of the output chrono::time_point
is the same as Window's FILETIME: 100-ns precision:
#include "date.h"
#include <string>
#include <iostream>
using filetime_duration = std::chrono::duration<std::int64_t, std::ratio<1, 10000000>>;
using FileTime = std::chrono::time_point<std::chrono::system_clock, filetime_duration>;
// or more simply:
// using FileTime = date::sys_time<filetime_duration>;
FileTime
FILETIME_to_system_clock(std::uint64_t fileTime)
{
using namespace std;
using namespace std::chrono;
// filetime_duration has the same layout as FILETIME; 100ns intervals
// January 1, 1601 (NT epoch) - January 1, 1970 (Unix epoch):
constexpr seconds nt_to_unix_epoch{-11644473600};
const filetime_duration asDuration{static_cast<int64_t>(fileTime)};
return FileTime{asDuration + nt_to_unix_epoch};
}
int
main()
{
using namespace std::chrono;
std::string s = date::format("%F %T", FILETIME_to_system_clock(131400356659154461));
std::cout << s << '\n';
}
Output:
2017-05-23 17:54:25.9154461
Ways to Convert Unix/Linux time to Windows time
This is described in Converting a time_t Value to a File Time, which provides sample C code.
Summary:
filetime = (unixtime * 10000000) + 116444736000000000
0x3DE43B0C → 0x01C295C4:91150E00 (2002-11-27 03:25:00 +0000)
(Also helpful is How to recognize different types of timestamps from quite a long way away.)
Often it is easier to parse the human-readable timestamp, such as "2002-11-27 03:25:00" (printf %AF %AT
), using strptime()
or similar.
Related Topics
Statically Linking System Libraries, Libc, Pthreads, to Aid in Debugging
About the Binary Compatibility of Linux
C++ Delete Vector, Objects, Free Memory
How to Detect the Number of Physical Processors/Cores on Windows, MAC and Linux
Altering Dll Search Path for Static Linked Dll
Is There Any Reason to Check for a Null Pointer Before Deleting
Array Initialization Use Const Variable in C++
Is Inline Assembly Language Slower Than Native C++ Code
How Std::Bind Works with Member Functions
Remove C and C++ Comments Using Python
Why Isn't Malloc Filling Up Memory
Openprocess/Readprocessmemory/Writeprocessmemory/Closehandle Equivalent
Find Out If String Ends with Another String in C++
How to Explain Undefined Behavior to Know-It-All Newbies
Where Is the Lock for a Std::Atomic