8

First off, I know that this question was asked quite some times (although it seems that 90% are about converting Unix ts -> Windows). Secondly, I would add a comment to another accepted question where my problem would fit in instead of adding another one but I don't have enough reputation.

I saw the accepted solution in Convert Windows Filetime to second in Unix/Linux but am stuck at what I should pass to the function WindowsTickToUnixSeconds. Judging by the parameter name windowsTicks I tried GetTickCount but saw shortly after that this returns the ms since the system started but I need any reasonable count since the start of the Windows time (which seems to was in 1601?).

I saw that windows has a function for retrieving this time: GetSystemTime. I cannot pass the resulting struct to the proposed function in 1 as it is not a long long value.

Can't someone please just give a full working example for C or C++ without omitting such mad-driving details?

Community
  • 1
  • 1
Daniel
  • 143
  • 1
  • 1
  • 7

3 Answers3

15

And for people on Windows:

Int64 GetSystemTimeAsUnixTime()
{
   //Get the number of seconds since January 1, 1970 12:00am UTC
   //Code released into public domain; no attribution required.

   const Int64 UNIX_TIME_START = 0x019DB1DED53E8000; //January 1, 1970 (start of Unix epoch) in "ticks"
   const Int64 TICKS_PER_SECOND = 10000000; //a tick is 100ns

   FILETIME ft;
   GetSystemTimeAsFileTime(out ft); //returns ticks in UTC

   //Copy the low and high parts of FILETIME into a LARGE_INTEGER
   //This is so we can access the full 64-bits as an Int64 without causing an alignment fault
   LARGE_INTEGER li;
   li.LowPart  = ft.dwLowDateTime;
   li.HighPart = ft.dwHighDateTime;
 
   //Convert ticks since 1/1/1970 into seconds
   return (li.QuadPart - UNIX_TIME_START) / TICKS_PER_SECOND;
}

The name of the function matches the naming scheme used by other Windows functions. The Windows System Time is by definition UTC.

Function Return type Resolution
GetSystemTimeAsFileTime FILETIME struct 0.0000001 s
GetSystemTime SYSTEMTIME struct 0.001 s
GetSystemTimeAsUnixTime Int64 1 s
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
  • Great solution! However, why int64 when it fits into an int? 2,147,483,647 – The End of Time [Unix] = int max length 2,147,483,647. – Mecanik Sep 26 '22 at 07:13
  • 2
    @Mecanik [We use an Int64 because we're not terrible programmers](https://en.wikipedia.org/wiki/Year_2038_problem) – Ian Boyd Dec 02 '22 at 19:49
4

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(&ltime);
    printf("Current local time as unix timestamp: %li\n", ltime);

    struct tm* timeinfo = gmtime(&ltime); /* 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
Daniel
  • 143
  • 1
  • 1
  • 7
1

With the SYSTEMTIME structure set by GetSystemTime, it's easy to create a a struct tm (see asctime for a reference of the structure) and convert it to a "UNIX time stamp" using the mktime function.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621