37

Does anyone know an equivalent function of the gettimeofday() function in Windows environment? I am comparing a code execution time in Linux vs Windows. I am using MS Visual Studio 2010 and it keeps saying, identifier "gettimeofday" is undefined.

Oliver Old
  • 23
  • 5
Benny
  • 5,218
  • 5
  • 24
  • 28
  • 2
    possible duplicate of [What should I use to replace gettimeofday() on Windows?](http://stackoverflow.com/questions/1676036/what-should-i-use-to-replace-gettimeofday-on-windows) – James M Jun 05 '12 at 22:32

6 Answers6

86

Here is a free implementation:

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <stdint.h> // portable: uint64_t   MSVC: __int64 

// MSVC defines this in winsock2.h!?
typedef struct timeval {
    long tv_sec;
    long tv_usec;
} timeval;

int gettimeofday(struct timeval * tp, struct timezone * tzp)
{
    // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
    // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
    // until 00:00:00 January 1, 1970 
    static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);

    SYSTEMTIME  system_time;
    FILETIME    file_time;
    uint64_t    time;

    GetSystemTime( &system_time );
    SystemTimeToFileTime( &system_time, &file_time );
    time =  ((uint64_t)file_time.dwLowDateTime )      ;
    time += ((uint64_t)file_time.dwHighDateTime) << 32;

    tp->tv_sec  = (long) ((time - EPOCH) / 10000000L);
    tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
    return 0;
}
Michaelangel007
  • 2,798
  • 1
  • 25
  • 23
  • Very good. I have a code which was included this implementation. Exactely the same one, but I need to have this code working on Linux and I don't know how to do that. How I would implement this piece of code to compile in Linux using this same implementation using C++ or C? Thks – S4nD3r Mar 26 '16 at 00:45
  • 2
    @S4nD3r #ifdef _WIN32 ...includes lines above ... #else #include #endif ... See my usage on my Buddhabrot project: https://raw.githubusercontent.com/Michaelangel007/buddhabrot/master/buddhabrot.cpp – Michaelangel007 Apr 27 '16 at 16:36
  • I know this is old, why is tzp passed in, as it isn't referenced? – SPlatten May 15 '18 at 14:42
  • @SPlatten In order to be binary compatible with sys/time.h: int gettimeofday(struct timeval *tv, struct timezone *tz); int settimeofday(const struct timeval *tv, const struct timezone *tz); – Michaelangel007 May 18 '18 at 15:20
  • @SPlatten tz never should be anything but null... only case it is used, it happens in linux kernel and is earmarked as deprecated. – Swift - Friday Pie Sep 18 '18 at 14:25
18

GetLocalTime() for the time in the system timezone, GetSystemTime() for UTC. Those return the date/time in a SYSTEMTIME structure, where it's parsed into year, month, etc. If you want a seconds-since-epoch time, use SystemTimeToFileTime() or GetSystemTimeAsFileTime(). The FILETIME is a 64-bit value with the number of 100ns intervals since Jan 1, 1601 UTC.

For interval taking, use GetTickCount(). It returns milliseconds since startup.

For taking intervals with the best possible resolution (limited by hardware only), use QueryPerformanceCounter().

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
10

This is the version of c++11 that uses chrono.

Thank you, Howard Hinnant for advice.

#if defined(_WIN32)
#include <chrono>

int gettimeofday(struct timeval* tp, struct timezone* tzp) {
  namespace sc = std::chrono;
  sc::system_clock::duration d = sc::system_clock::now().time_since_epoch();
  sc::seconds s = sc::duration_cast<sc::seconds>(d);
  tp->tv_sec = s.count();
  tp->tv_usec = sc::duration_cast<sc::microseconds>(d - s).count();

  return 0;
}

#endif // _WIN32
lilucpp
  • 196
  • 1
  • 10
4

If you really want a Windows gettimeofday() implementation, here is one from PostgreSQL that uses Windows APIs and the proper conversions.

However if you want to time code, I suggest you look into QueryPerformanceCounter() or by directly invoking the TSC if you're only going to run on x86 for example.

NuSkooler
  • 5,391
  • 1
  • 34
  • 58
4

Nowadys I would use the following for gettimeofday() on Windows, which is using GetSystemTimePreciseAsFileTime() if compiled for Windows 8 or higher and GetSystemTimeAsFileTime() otherwise:

#include <Windows.h>
struct timezone {
    int tz_minuteswest;
    int tz_dsttime;
};

int gettimeofday(struct timeval *tv, struct timezone *tz)
{
    if (tv) {
        FILETIME               filetime; /* 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 00:00 UTC */
        ULARGE_INTEGER         x;
        ULONGLONG              usec;
        static const ULONGLONG epoch_offset_us = 11644473600000000ULL; /* microseconds betweeen Jan 1,1601 and Jan 1,1970 */

#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
        GetSystemTimePreciseAsFileTime(&filetime);
#else
        GetSystemTimeAsFileTime(&filetime);
#endif
        x.LowPart =  filetime.dwLowDateTime;
        x.HighPart = filetime.dwHighDateTime;
        usec = x.QuadPart / 10  -  epoch_offset_us;
        tv->tv_sec  = (time_t)(usec / 1000000ULL);
        tv->tv_usec = (long)(usec % 1000000ULL);
    }
    if (tz) {
        TIME_ZONE_INFORMATION timezone;
        GetTimeZoneInformation(&timezone);
        tz->tz_minuteswest = timezone.Bias;
        tz->tz_dsttime = 0;
    }
    return 0;
}
Holger
  • 3,920
  • 1
  • 13
  • 35
0

Since Visual Studio 2015, timespec_get is available:

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static uint64_t
time_ns(void)
{
    struct timespec ts;

    if (timespec_get(&ts, TIME_UTC) != TIME_UTC)
    {
        fputs("timespec_get failed!", stderr);
        return 0;
    }
    return 1000000000 * ts.tv_sec + ts.tv_nsec;
}

int main(void)
{
    printf("%" PRIu64 "\n", time_ns());
    return EXIT_SUCCESS;
}

Compile using cl t.c and run:

C:\> perl -E "system 't' for 1 .. 10"
1626610781959535900
1626610781973206600
1626610781986049300
1626610781999977000
1626610782014814800
1626610782028317500
1626610782040880700
1626610782054217800
1626610782068346700
1626610782081375500
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339