title: C++ timegm conversion DST to a certain timezone at a given time in the future?
body: <p>I need an accurate conversion in my class from UTC time to local time of a given timezone, with or without DST in effect. My problem is, that when I use <code>struct tm</code> I have to provide the tm_isdst member, or leave it -1 to be determined automatically.</p>
  
  <pre><code>from mktime(3) - linux man page:
  "The value specified in the tm_isdst field informs mktime() whether or not daylight saving time (DST) is in effect for the time supplied in the tm structure:
  a positive value means DST is in effect;
  zero means that DST is not in effect;
  and a negative value means that mktime() should (use timezone information and system databases to) attempt to determine whether DST is in effect at the specified time.
  </code></pre>
  
  <p>Now here's my problem. I'm working with exchanges from all over the globe (from Chicago, New York, Sao Paolo, Melbourne, Buenos Aires, Johannesburg, Shanghai, Seoul ...). I have a table with the name of each timezone for each of the exchanges: for example Africa/Johannesburg, America/Chicago, America/Winnipeg.</p>
  
  <p>The data I'm working on is expiration for some given futures and options financial instruments. The data I'm receiving is always in UTC, and I need to convert to the local time of the exchange. </p>
  
  <p>Long story short, my current implementation is adding 1 extra hour to the expiration time of those assets that should not have the DST in effect (for example an instrument that expires in December and local time is America/Chicago, should add -360 minutes offset and DST 0, while another one which expires in June in the same timezone should have -360 timezone offset +60 DST offset, which would be -300 offset to the UTC timestamp. What I'm currently having the problem with, for example for the month of December I get 9:30 AM instead of 8:30 AM as the UTC timestamp contains the dst offset already.</p>
  
  <p>Here is my function for doing the conversion, which is obviously broken:</p>
  
  <pre><code>#ifdef WIN32
  #define timegm _mkgmtime
  #endif
  
  SimpleDateTime BusinessDateCalculator::UTC2TZ(const SimpleDateTime&amp; utcDateTime, const int tz_utc_offset, const int tz_dst)
  {
      struct tm stm;
      memset(&amp;stm, 0, sizeof(stm));
      stm.tm_year = utcDateTime.getYear() - 1900;
      stm.tm_mon = utcDateTime.getMonth() - 1;
      stm.tm_mday = utcDateTime.getDay();
      stm.tm_hour = utcDateTime.getHour();
      stm.tm_min = utcDateTime.getMinute();
      stm.tm_sec = utcDateTime.getSecond();
      stm.tm_isdst = -1; //see note at the top of this file
  
      time_t tt = timegm( &amp;stm );
      tt += (tz_utc_offset + tz_dst) * 60;
  
      struct tm ntm;
      memset(&amp;ntm, 0, sizeof(ntm));
      gmtime_r( &amp;tt, &amp;ntm );
      return SimpleDateTime(ntm.tm_year + 1900, ntm.tm_mon + 1, ntm.tm_mday, ntm.tm_hour, ntm.tm_min, ntm.tm_sec, utcDateTime.getMillisecond());
  }
  </code></pre>
  
  <p>Where SimpleDateTime is a date-time class with additional functionality, like conversion from different date/time formats (SQL, FIX, Timeonly, DateOnly).</p>
  
  <p>I have the timezone information of a certain exchange available at all time. My question can I provide the timezone name somehow, and let the <code>timegm</code> perform a database search and determine whether in the America/Chicago timezone the DST is or is not in effect on 2014-12-19 and accordingly not add the extra 60 minutes to the UTC time, and on the same date for example in the southern hemisphere timezone America/Sao_Paulo it is in effect until 16 Feb 2015, and for this timestamp it should add 60 minutes to get the correct local time for the given date.</p>