Convert UTC to Local Time

I spent a couple of hours googling for help with a seemingly simple problem – I just wanted to convert a timestamp expressed in UTC (former GMT) to a local timestamp. The solution was indeed very simple, but hard to find on the net. This little page is kept in order to increase the search target area for any fellow coder …

/*
    C source code example: Convert UTC to local time zone, considering daylight
    savings. Uses mktime(), gmtime() and localtime(). Works for dates between
    years 1902 and 2037. Should compile and run with any recent GNU C if your
    tzdata is healthy. Written by Robert Larsson  https://rl.se

    Code put in public domain; do what you want with it.
*/

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

#define     DESTZONE    'TZ=Europe/Stockholm'       // Our destination time zone

int main(void)
{
    struct tm   i;
    time_t      stamp;                              // Can be negative, so works before 1970

    putenv('TZ=UTC');                               // Begin work in Greenwich …

    i.tm_year = 2009-1900;                          // Populate struct members with
    i.tm_mon  = 8-1;                                // the UTC time details, we use
    i.tm_mday = 29;                                 // 29th August, 2009 12:34:56
    i.tm_hour = 12;                                 // in this example
    i.tm_min  = 34;
    i.tm_sec  = 56;

    stamp = mktime(&i);                             // Convert the struct to a Unix timestamp

    putenv(DESTZONE);                               // Switch to destination time zone

    printf('UTC  : %s', asctime(gmtime(&stamp)));
    printf('Local: %s', asctime(localtime(&stamp)));

    return 0;                                       // That’s it, folks.
}
As you see, the trick is to insert putenv() at strategic places. Note that gmtime() and localtime() are not thread safe, see their man pages for explanations and alternatives. For a list of valid time zone names, see this list at Wikipedia.