C ++ time_t的问题 [英] C++ time_t problem

查看:255
本文介绍了C ++ time_t的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在用C ++(VS 2008)。

日期管理麻烦

根据 MSDN规格 time_t的重新presents:

自1970年1月1日的秒数,0:00 UTC

因此​​,我写了这片code的:

 的#include<&stdio.h中GT;
#包括LT&;&time.h中GT;time_t的GETDATE(INT年,月整型,诠释天,诠释小时,INT分钟,INT秒)
{
    time_t的rawtime;
    结构TM * timeinfo;    时间(安培; rawtime);
    timeinfo = gmtime的(安培; rawtime);
    timeinfo-> tm_year =年 - 1900;
    timeinfo-> tm_mon =月 - 1;
    timeinfo-> tm_mday =天;
    timeinfo-> tm_hour =小时;
    timeinfo-> tm_min =分钟;
    timeinfo-> tm_sec =秒;
    timeinfo->的tm_isdst = 0; //禁用夏令时    time_t的RET = mktime(timeinfo);    返回RET;
}诠释的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!
    返回0;
}

这似乎是1小时(即零时间为1970年1月1日,下午1:00 UTC)。

起初,我以为这个问题可能来自夏季时间标志,但它并没有改变其更改。

我是不是做错了什么?

在此先感谢


P.S。
从理论上讲,我可能不会介意零时间价值,因为它只是一个参考时间。

但我需要肯定的价值,因为我端起了code到另一种语言,我需要得到完全相同的结果。


编辑:

这里的解决方案,这要归功于乔许·凯利回答

  time_t的mktimeUTC(结构TM * timeinfo)
{
    // ***在UTC模式下输入
    字符* oldTZ = GETENV(TZ);
    传给putenv(TZ = UTC);
    _tzset();
    // ***    time_t的RET = mktime(timeinfo);    // ***恢复previous TZ
    如果(oldTZ == NULL)
    {
        传给putenv(TZ =);
    }
    其他
    {
        字符的buff [255];
        sprintf的(BUFF,TZ =%S,oldTZ);
        传给putenv(BUFF);
    }
    _tzset();
    // ***    返回RET;
}


解决方案

mktime 需要结构TM 给人一种本地时间和返回自0:00 1970年1月1日,秒数的 UTC 。因此,你的 GETDATE(1970,1,1,0,0,0); 调用将返回0,如果您的本地时区是UTC,但可能对其他时间返回其他值区域。

编辑:有关的UTC版本 mktime GETDATE ,尝试下面(未经测试):


  1. GETENV 保存TZ环境变量的当前值(如果有的话)。

  2. 传给putenv 改变TZ环境变量设置为UTC。

  3. _tzset 进行更改活跃。

  4. 呼叫 mktime

  5. 恢复TZ的旧值,然后调用 _tzset 试。

I'm having trouble with dates management in C++ (VS 2008).

According to MSDN specifications, time_t represents:

The number of seconds since January 1, 1970, 0:00 UTC

therefore, I've written this piece of code:

#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;
}

It seems to be shifted by 1 hour (i.e. zero time is January 1, 1970, 1:00 UTC).

Initially, I thought the problem could come from the DayLightSaving flag, but it doesn't change by changing it.

Am I doing something wrong ?

Thanks in advance


P.S. In theory, I might not mind the zero time value, because it's only a reference time.

But I need to be sure about the value, because I'm porting the code to another language and I need to get exactly the same results.


EDIT:

here's the solution, thanks to 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;
}

解决方案

mktime takes a struct tm giving a local time and returns the number of seconds since January 1, 1970, 0:00 UTC. Therefore, your GetDate(1970,1,1,0,0,0); call will return 0 if your local time zone is UTC but may return other values for other time zones.

Edit: For a UTC version of mktime or your GetDate, try the following (untested):

  1. Call getenv to save the current value of the TZ environment variable (if any).
  2. Call putenv to change the TZ environment variable to "UTC".
  3. Call _tzset to make your changes active.
  4. Call mktime.
  5. Restore the old value of TZ, then call _tzset again.

这篇关于C ++ time_t的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆