std::mktime and timezone info

timestamp = mktime(&tm) - _timezone;

or platform independent way:

 timestamp = mktime(&tm) - timezone;

If you look in the source of mktime() on line 00117, the time is converted to local time:

seconds += _timezone;

mktime() uses tzname for detecting timezone. tzset() initializes the tzname variable from the TZ enviroment variable. If the TZ variable appears in the enviroment but its value is empty or its value cannot be correctly interpreted, UTC is used.

A portable (not threadsafe) version according to the timegm manpage

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

   time_t
   my_timegm(struct tm *tm)
   {
       time_t ret;
       char *tz;

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

Eric S Raymond has a threadsafe version published in his article Time, Clock, and Calendar Programming In C

time_t my_timegm(register struct tm * t)
/* struct tm to seconds since Unix epoch */
{
    register long year;
    register time_t result;
#define MONTHSPERYEAR   12      /* months per calendar year */
    static const int cumdays[MONTHSPERYEAR] =
        { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };

    /*@ +matchanyintegral @*/
    year = 1900 + t->tm_year + t->tm_mon / MONTHSPERYEAR;
    result = (year - 1970) * 365 + cumdays[t->tm_mon % MONTHSPERYEAR];
    result += (year - 1968) / 4;
    result -= (year - 1900) / 100;
    result += (year - 1600) / 400;
    if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0) &&
        (t->tm_mon % MONTHSPERYEAR) < 2)
        result--;
    result += t->tm_mday - 1;
    result *= 24;
    result += t->tm_hour;
    result *= 60;
    result += t->tm_min;
    result *= 60;
    result += t->tm_sec;
    if (t->tm_isdst == 1)
        result -= 3600;
    /*@ -matchanyintegral @*/
    return (result);
}

mktime assumes that the date value is in the local time zone. Thus you can change the timezone environment variable beforehand (setenv) and get the UTC timezone.

Windows tzset

Can also try looking at various home-made utc-mktimes, mktime-utcs, etc.

Tags:

C++