title: timegm cross platform
body: <p>I'm using Visual Studio c++ Compiler ( 2010 ), but the library has different implementation of ANSI C and POSIX libraries function. </p></p>
  
  <p>What is the difference between ANSI C function and Windows CRT implementation? For example what is the difference between <code>tzset()</code> and <code>_tzset()</code> or <code>setenv()</code> ans <code>_setenv()</code>? It seems the do the same thing in the same way...</p>
  
  <p>I'm using msvc ( 2010 ), have I to prefer the Windows CRT Implementation?</p>
  
  <p><b> EDIT 1 </b></p>
  
  <p>Well I want convert in a portable way a struct tm expressed in UTC in a <code>time_t</code>, but there's no portable way to do that. I've to write the function for different platform (Android, Linux, Windows, Windows CE ).</p>
  
  <p>I've seen <a href="https://stackoverflow.com/questions/283166/easy-way-to-convert-a-struct-tm-expressed-in-utc-to-time-t-type/">this stackoverflow post</a> that uses <code>setenv</code>, <code>getenv</code> and <code>tzset</code></p>
  
  <p><b> Edit2 </b></p>
  
  <p>Unfortunately after some test I've discovered that <code>getenv("TZ")</code> returns a null pointer on windows. But why is so difficult transform a UTC time struct to a <code>time_t</code>?</p>
  
  <p><b> Edit 3 </b></p>
  
  <p>
  From Boost I discovered this fragment of code in boost/chrono/io/time_point_io.hpp. Hope this helps me.
  </p>
  
  <pre><code>inline int32_t is_leap(int32_t year)
  {
    if(year % 400 == 0)
    return 1;
    if(year % 100 == 0)
    return 0;
    if(year % 4 == 0)
    return 1;
    return 0;
  }
  inline int32_t days_from_0(int32_t year)
  {
    year--;
    return 365 * year + (year / 400) - (year/100) + (year / 4);
  }
  inline int32_t days_from_1970(int32_t year)
  {
    static const int days_from_0_to_1970 = days_from_0(1970);
    return days_from_0(year) - days_from_0_to_1970;
  }
  inline int32_t days_from_1jan(int32_t year,int32_t month,int32_t day)
  {
    static const int32_t days[2][12] =
    {
      { 0,31,59,90,120,151,181,212,243,273,304,334},
      { 0,31,60,91,121,152,182,213,244,274,305,335}
    };
    return days[is_leap(year)][month-1] + day - 1;
  }
  
  inline time_t internal_timegm(std::tm const *t)
  {
    int year = t-&gt;tm_year + 1900;
    int month = t-&gt;tm_mon;
    if(month &gt; 11)
    {
      year += month/12;
      month %= 12;
    }
    else if(month &lt; 0)
    {
      int years_diff = (-month + 11)/12;
      year -= years_diff;
      month+=12 * years_diff;
    }
    month++;
    int day = t-&gt;tm_mday;
    int day_of_year = days_from_1jan(year,month,day);
    int days_since_epoch = days_from_1970(year) + day_of_year;
  
    time_t seconds_in_day = 3600 * 24;
    time_t result = seconds_in_day * days_since_epoch + 3600 * t-&gt;tm_hour + 60 * t-&gt;tm_min + t-&gt;tm_sec;
  
    return result;
  }
  </code></pre>