The gettimeofday() Function

Every so often I scour C library references, looking for fun or unusual functions. When I find one I’m unfamiliar with or something I’ve seldom used, I write about. After all, the functions do practical things that might be worthy of exploration. A recent example is gettimeofday().

The gettimeofday() is defined in the sys/time.h header. Like many get* functions, it has a companion, settimeofday(). Yep, these are system functions.

The gettimeofday() function fills two structures with details about (you guessed it) the current time of day:

int gettimeofday( struct timeval *, struct tzp *);

The timeval structure contains two members, time_t variable tv_sec and suseconds_t variable tv_usec. The first, tv_sec, is a time_t value, the number of seconds elapsed since January 1, 1970. The second is a microsecond value, which the computer knows but isn’t included with the time_t value.

The tzp structure contains two members relevant to time zone information: int tz_minuteswest which is the number of minutes west of GMT for the system’s current time zone. Some member tz_dsttime is an integer that indicates the number of hours to adjust for daylight saving time. These are time details not readily available in the other time functions.

The companion settimteofday() function uses the same arguments, but with the structures passed setting various time tidbits. This function can be called only by the superuser, so my focus in this post is on gettimeofday().

The gettimeofday() function returns 0 upon success and -1 on failure. The errno variable is set when the function fails.

Here’s my gettimeofday() test program:

2020_07_11-Lesson-a.c

#include <stdio.h>
#include <sys/time.h>

int main()
{
    struct timeval tv;
    struct timezone tz;

    gettimeofday(&tv,&tz);

    printf("Seconds since 1/1/1970: %lu\n",tv.tv_sec);
    printf("Microseconds: %d\n",tv.tv_usec);
    printf("Minutes west of Greenwich: %d\n",tz.tz_minuteswest);
    printf("Daylight Saving Time adjustment: %d\n",tz.tz_dsttime);

    return(0);
}

The gettimeofday() function’s structure arguments are declared at Lines 6 and 7. If you declare them as pointers, ensure that you assign them to an address. Pointers passed to the function can be set to NULL, though if both are set to NULL the function won’t fill them.

Here is the program’s output:

Seconds since 1/1/1970: 1593275915
Microseconds: 613564
Minutes west of Greenwich: 480
Daylight Saving Time adjustment: 1

Obviously this data isn’t quite useful, thought I’m certain some nerd somewhere can read a raw time_t value. Here is an improvement to the code:

2020_07_11-Lesson-b.c

#include <stdio.h>
#include <sys/time.h>
#include <time.h>

int main()
{
    struct timeval tv;
    struct timezone tz;
    struct tm *today;
    int zone;

    gettimeofday(&tv,&tz);

    /* get time details */
    today = localtime(&tv.tv_sec);
    printf("It's %d:%0d:%0d.%d\n",
            today->tm_hour,
            today->tm_min,
            today->tm_sec,
            tv.tv_usec
          );
    /* set time zone value to hours, not minutes */
    zone = tz.tz_minuteswest/60;
    /* calculate for zones east of GMT */
    if( zone > 12 )
        zone -= 24;
    printf("Time zone: GMT %+d\n",zone);
    printf("Daylight Saving Time adjustment: %d\n",tz.tz_dsttime);

    return(0);
}

I added the localtime() function to deal with the time_t value from tv.tv_sec. This value is translated into a clock value HH:MM:SS plus the microsecond value, output at Lines 16 through 21.

The time zone value from tz.tz_minuteswest is saved in the zone variable. Lines 25 and 26 adjust this value to account for time zones east of GMT. This result is output at Line 27. The %+d placeholder ensures that a sign, + or – prefixes the value.

Here’s the output:

It's 10:15:23.952229
Time zone: GMT +8
Daylight Saving Time adjustment: 1

I’m uncertain as to how I could use gettimeofday() function as the other time function have suited my needs. Still, this function is available and I’m glad I found it.

2 thoughts on “The gettimeofday() Function

  1. “thought I’m certain some nerd somewhere can read a raw time_t value”

    If you convert a time_t to a tm using gmtime or localtime you get a tm struct which has 9 ints representing the various components, hours,minutes, seconds, day, month, year etc.

    I expect Dustin Hoffman can look at a number such as 1593275915 and tell you the date and time immediately.

  2. I had to reverse calculate a time_t value once, so I knew the values for a specific day. But beyond that . . . time for Wopner.

Leave a Reply