C code to get local time offset in minutes relative to UTC?

chmike picture chmike · Sep 6, 2015 · Viewed 9.1k times · Source

I didn't find a trivial way to get the time offset in minutes between the local time and the UTC time.

At first I intended to use tzset() but it doesn't provide the daylight saving time. According to the man page, it is simply an integer different of zero if day light saving is in effect. While it is usually an hour, it may be half an hour in some country.

I would prefer avoiding to compute the time difference between current UTC returned by gmtime() and localtime().

A more general solution would give me this information for a specified location and a positive time_t value, or at least locally.

Edit 1: the use case is to get the right local time offset for https://github.com/chmike/timez. BTW, If you thought libc functions to manipulate time were Ok, read this https://rachelbythebay.com/w/2013/03/17/time/.

Edit 2: the best and simplest solution I have so far to compute the time offset to UTC in minutes is

// Bogus: assumes DST is always one hour
tzset();
int offset = (int)(-timezone / 60 + (daylight ? 60 : 0));

The problem is to determine the real day light saving time.

Edit 3: Inspired by the answer of @trenki, I came up with the following solution. This is a hack in that it tricks mktime() to consider the output of gmtime() as the localtime. The result is inaccurate when the DST change is in the time span between UTC time and localtime.

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

int main()
{
    time_t rawtime = time(NULL);
    struct tm *ptm = gmtime(&rawtime);
    // Request that mktime() looksup dst in timezone database
    ptm->tm_isdst = -1;                
    time_t gmt = mktime(ptm);
    double offset = difftime(rawtime, gmt) / 60;
    printf("%f\n", offset);
    return 0;
}

Answer

trenki picture trenki · Sep 7, 2015

This C code computes the local time offset in minutes relative to UTC. It assumes that DST is always one hour offset.

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

int main()
{
    time_t rawtime = time(NULL);
    struct tm *ptm = gmtime(&rawtime);
    time_t gmt = mktime(ptm);
    ptm = localtime(&rawtime);
    time_t offset = rawtime - gmt + (ptm->tm_isdst ? 3600 : 0);

    printf("%i\n", (int)offset);
}

It uses gmtime and localtime though. Why don't you want to use those functions?