C++ time_t问题

dig*_*All 8 c c++ time visual-studio-2008

我在C++中使用日期管理遇到了麻烦(VS 2008).

根据MSDN规范,time_t代表:

自1970年1月1日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;
}
Run Code Online (Sandbox Code Playgroud)

它似乎被移动了1小时(即零时间是1970年1月1日,1:00 UTC).

最初,我认为问题可能来自DayLightSaving标志,但它不会通过更改它而改变.

难道我做错了什么 ?

提前致谢


PS理论上,我可能不介意零时间值,因为它只是一个参考时间.

但我需要确定价值,因为我将代码移植到另一种语言,我需要得到完全相同的结果.


编辑:

这是解决方案,感谢Josh Kelley答案

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;
}
Run Code Online (Sandbox Code Playgroud)

Jos*_*ley 8

mktime需要struct tm给予本地时间,自1970年1月1日晚上12点返回的秒数UTC.因此,GetDate(1970,1,1,0,0,0);如果您的本地时区是UTC ,则您的呼叫将返回0,但可能会返回其他时区的其他值.

编辑:对于UTC mktime或您的UTC版本,请GetDate尝试以下(未经测试):

  1. 调用getenv以保存TZ环境变量的当前值(如果有).
  2. 调用putenv将TZ环境变量更改为"UTC".
  3. 致电_tzset使您的更改生效.
  4. 打电话mktime.
  5. 恢复TZ的旧值,然后_tzset再次调用.