代码之家  ›  专栏  ›  技术社区  ›  digEmAll

C++时间问题

  •  8
  • digEmAll  · 技术社区  · 14 年前

    我在C++中使用日期管理遇到困难(VS 2008)。

    根据 MSDN specifications 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;
    }
    

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

    起初,我认为问题可能来自于DayLightSaving标志,但它并没有改变它。

    我做错什么了吗?

    提前谢谢


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


    编辑:

    Josh Kelley Answer

    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 回复  |  直到 4 年前
        1
  •  8
  •   Josh Kelley    14 年前

    mktime struct tm 给予 地方的 时间并返回自1970年1月1日0:00以来的秒数 GetDate(1970,1,1,0,0,0); 如果本地时区是UTC,则调用将返回0,但可能会返回其他时区的其他值。

    编辑: 对于UTC版本的 或者你的 GetDate ,请尝试以下操作(未测试):

    1. getenv 保存TZ环境变量的当前值(如果有)。
    2. putenv
    3. 呼叫 _tzset
    4. mktime公司
    5. 恢复TZ的旧值,然后调用 _tzset公司
        2
  •  1
  •   Hogan    14 年前

    只是摇摇晃晃,但请尝试以下操作:

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