我正在执行下面的代码。
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'在程序中,这是正确的工作,这是混乱的。
输出-〉
[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]$
我系统上的日期信息,--〉
[user@rtpkvm55-vm2 root]$ date
Sat Aug 25 08:28:26 EDT 2012
4条答案
按热度按时间q35jwt9p1#
"会发生什么"
您指定的日期使用夏令时,但是当调用
mktime
时,storage.tm_isdst
为零。mktime
看到这一点并认为“嘿,他们给我的日期带有错误的夏令时标志,让我们来修正它”。然后它将tm_isdst
设置为1并更改tm_hour
。另请参见this答案。
去弥补
timegm
代替mktime
mktime
之前将时区设置为UTC(另请参见timegm
中的示例):boost::locale::date_time
页面上的问答部分)guykilcj2#
哇,这是没有办法的,这一定是系统实现mktime(3)中的一个bug,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 *
,我错了,规范化值是正确的行为。ncecgwcz3#
你必须在
tm
结构体中设置tm_isdst
,否则它是未初始化的,因此被设置为一个随机垃圾值。然后,当你根据tm_isdst
变量中的随机垃圾调用mktime
时,它要么应用夏令时,要么不应用,看起来不可预测。但是,如果您将其设置为
-1
,则会告诉mktime
您不知道夏令时是否生效,因此第一次调用mktime
将修复它。因此,解决此问题的最简单方法是添加:
然后调用
mktime
。ycggw6v24#
下面是修复代码的技巧: