C++ проблема времени t

у меня проблемы с управлением датами в C++ (VS 2008).

По данным MSDN технические характеристики, time_t представляет:

количество секунд с 1 января 1970 года, 0: 00 UTC

поэтому я написал этот кусок кода:

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

time_t GetDate(int year, int month, int day, int hour, int min, int sec)
{
    time_t rawtime;
    struct tm * timeinfo;

    time ( &rawtime );
    timeinfo = gmtime ( &rawtime );
    timeinfo->tm_year = year - 1900;
    timeinfo->tm_mon = month - 1;
    timeinfo->tm_mday = day;
    timeinfo->tm_hour = hour;
    timeinfo->tm_min = min;
    timeinfo->tm_sec = sec;
    timeinfo->tm_isdst = 0; // disable daylight saving time

    time_t ret = mktime ( timeinfo );

    return ret;
}

int main ()
{
    time_t time_0 = GetDate(1970,1,1,0,0,0);
    // time_0 == -1 !!!
    time_t time_1 = GetDate(1970,1,1,1,0,0);
    // time_1 == 0 !!!
    return 0;
}

похоже, что он сдвинут на 1 час (т. е. нулевое время-1 января 1970 года, 1:00 UTC).

Первоначально я думал, что проблема может исходить из Времени флаг, но это не меняет, изменяя его.

Я делаю что-то неправильно ?

спасибо заранее


С. П. Теоретически, я мог бы не возражать против нулевого значения времени, потому что это только эталонное время.

но мне нужно быть уверенным в значении, потому что я портирую код на другой язык, и мне нужно получить точно такие же результаты.


EDIT:

вот решение, спасибо Джош Келли Ответ

time_t mktimeUTC(struct tm* timeinfo)
{
    // *** enter in UTC mode
    char* oldTZ = getenv("TZ");
    putenv("TZ=UTC");
    _tzset();
    // ***

    time_t ret = mktime ( timeinfo );

    // *** Restore previous TZ
    if(oldTZ == NULL)
    {
        putenv("TZ=");
    }
    else
    {
        char buff[255];
        sprintf(buff,"TZ=%s",oldTZ);
        putenv(buff);
    }
    _tzset();
    // ***

    return ret;
}

2 ответов


mktime принимает struct tm дав местные время и возвращает количество секунд с 1 января 1970 года, 0: 00 UTC. Следовательно, ваш GetDate(1970,1,1,0,0,0); вызов вернет 0, если ваш локальный часовой пояс UTC, но может возвращать другие значения для других часовых поясов.

Edit: для версии UTC mktime или GetDate, попробуйте следующее (непроверенных):

  1. вызов getenv для сохранения текущего значения переменная среды TZ (если есть).
  2. вызов putenv чтобы изменить переменную среды TZ на "UTC".
  3. вызов _tzset сделать активным изменений.
  4. вызов mktime.
  5. восстановите старое значение TZ, затем вызовите _tzset снова.

просто шутка, но попробуйте следующее:

timeinfo->tm_year = year - (unsigned long)1900;
timeinfo->tm_mon = month - (unsigned long)1;