Badr
Badr

Reputation: 10658

UTC to Time of the day in ANSI C?

how to convert the utc time to local time of the day?

Upvotes: 4

Views: 1943

Answers (2)

Đẹp Trai
Đẹp Trai

Reputation: 31

M. MARIE's answer does not in fact work for the question as posed: tzset() is POSIX, but not ANSI C as the title of the original question asked. There is no mention of it in either C90 or C99 (from searching the draft standards; I have no access to the final standards).

OP's question is perhaps a little vague as it is not clear what he means by "utc time", but presumably he means broken-down components, let's say filled into a struct tm.

It is possible in C99 to determine local TZ's offset from UTC by parsing the output of strftime("%z",...) (make sure that you call it with your own date values, as this offset will change over time); but this format-code is not available in C90, so AFAIK you're out of luck if you must conform to C90, unless you want to try to parse the output of strftime("%Z",...), but that's going to be fundamentally non-portable.

You then could convert your UTC components to time_t using mktime(), although they will be interpreted as in the local timezone; then apply the offset, and convert back to broken-down components using localtime(). You may run into edge cases around the time when your local timezone switches to and from DST (or when changes to your timezone's offset where effected), but this can be easily avoided by moving to a locale that does not use DST, or ameliorated by setting tm_dst to 0 when calling both strftime() and mktime().

Alternatively, don't restrict yourself to ANSI C.

Upvotes: 3

Patrick
Patrick

Reputation: 2405

You must use a mix of tzset() with time/gmtime/localtime/mktime functions.

Try this:

#include <stdio.h>
#include <stdlib.h>

#include <time.h>

time_t makelocal(struct tm *tm, char *zone)
{
    time_t ret;
    char *tz;

    tz = getenv("TZ");
    setenv("TZ", zone, 1);
    tzset();
    ret = mktime(tm);
    if(tz)
        setenv("TZ", tz, 1);
    else
        unsetenv("TZ");
    tzset();
    return ret;
}

int main(void)
{
    time_t gmt_time;
    time_t local_time;
    struct tm *gmt_tm;

    gmt_time = time(NULL);
    gmt_tm = gmtime(&gmt_time);
    local_time = makelocal(gmt_tm, "CET");

    printf("gmt: %s", ctime(&gmt_time));
    printf("cet: %s", ctime(&local_time));

    return 0;
}

Basically, this program takes the current computer day as GMT (time(NULL)), and convert it to CET:

$ ./tolocal 
gmt: Tue Feb 16 09:37:30 2010
cet: Tue Feb 16 08:37:30 2010

Upvotes: 5

Related Questions