我在代码下面执行。
int main()
{
struct tm storage={0,0,0,0,0,0,0,0,0};
char *p = NULL;
p = (char *)strptime("2012-08-25 12:23:12","%Y-%m-%d %H:%M:%S",&storage);
char buff[1024]={0};
strftime(buff,1024,"%Y-%m-%d %H:%M:%S",&storage);
cout << buff << endl;
storage.tm_sec += 20;
strftime(buff,1024,"%Y-%m-%d %H:%M:%S",&storage);
cout << buff << endl;
mktime(&storage);
strftime(buff,1024,"%Y-%m-%d %H:%M:%S",&storage);
cout << buff << endl;
return 0;
}
如果以上程序执行,则打印'2012-08-25 13:23:32'而不是'2012-08-25 12:23:32'。请帮助,为什么它增加了tm_hour值。 如果我在程序中输入日期为“2012-02-25 12:23:32”,这可以正常工作,这很令人困惑。
OUtput - &gt;
[user@rtpkvm55-vm2 root]$ ./a.out
2012-08-25 12:23:12
2012-08-25 12:23:32
2012-08-25 13:23:32
[user@rtpkvm55-vm2 root]$
我系统上的日期信息, - &gt;
[user@rtpkvm55-vm2 root]$ date
Sat Aug 25 08:28:26 EDT 2012
答案 0 :(得分:15)
会发生什么
您指定的日期有夏令时生效,但在调用mktime
时,storage.tm_isdst
为零。 mktime
看到了这一点,并认为“嘿,他们给了我一个日期不正确的夏令时标志,让我们解决它”。然后,它将tm_isdst
设置为1并更改tm_hour
。
另见this答案。
修复
timegm
代替mktime
mktime
之前将时区设置为UTC(另请参阅timegm
中的示例):
setenv("TZ", "", 1); tzset(); mktime();
boost::locale::date_time
页面上的问答部分)答案 1 :(得分:4)
哇,没有办法绕过它。它必须是系统执行mktime(3)中的错误。 mktime(3)不应该改变传递给它的 struct tm *
。
我建议检查storage.tm_isdst
的值。尝试将其设置为0以确保它不会与DST混淆。如果这不起作用,请尝试将其设置为-1以使其自动确定正确的值。
mktime - convert broken-down time into time since the Epoch
tm_isdst的正值或0值会导致mktime()最初假设夏令时分别在指定时间内有效或无效。 tm_isdst的负值会导致mktime()尝试确定夏令时是否在指定时间内有效。
我错误的是mktime(3)没有修改struct tm *
。标准化值是正确的行为。
答案 2 :(得分:0)
您必须在 tm_isdst
结构中设置 tm
否则它是未初始化的,因此被设置为随机垃圾值。然后,当您根据 mktime
变量中的随机垃圾调用 tm_isdst
时,它要么应用夏令时,要么不应用,似乎不可预测。
但是,如果您将其设置为 -1
,您会告诉 mktime
您不知道夏令时是否生效,因此对 mktime
的第一次调用将修复它.
因此,解决此问题的最简单方法是添加:
storage.tm_isdst = -1;
在调用 mktime
之前。