将struct tm转换为time_t

18

I have the following code:

struct tm time;

strptime("27052010", "%d%m%Y", &time);

cout << "sec: " << time.tm_sec << "\n";
cout << "min: " << time.tm_min << "\n";
cout << "hour: " << time.tm_hour << "\n";
cout << "day: " << time.tm_mday << "\n";
cout << "month: " << (time.tm_mon + 1) << "\n";
cout << "year: " << time.tm_year << "\n";

time_t t = mktime(&time);

cout << "sec: " << time.tm_sec << "\n";
cout << "min: " << time.tm_min << "\n";
cout << "hour: " << time.tm_hour << "\n";
cout << "day: " << time.tm_mday << "\n";
cout << "month: " << (time.tm_mon + 1) << "\n";
cout << "year: " << time.tm_year << "\n";

cout << "time: " << t << "\n";

输出结果为:
sec: 1474116832
min: 32767
hour: 4238231
day: 27
month: 5
year: 110

sec: 52
min: 0
hour: 6
day: 2
month: 9
year: 640
time: 18008625652 (Fri, 02 Sep 2540 04:00:52 GMT)

我的问题是为什么mktime()会改变time的值,转换后的time_t为什么不等于我的输入日期。我期望输出的是自1970年以来以秒为单位表示的日期(2010年5月27日=1330905600)。
提前致谢。

2
在调用 mktime 函数之前,time.tm_hourtime.tm_mintime.tm_sec 的值是什么? - Wintermute
4
嗯……你取了一个未初始化的结构体,初始化了其中三个字段,然后“转换”了它(三个有意义的值加上许多垃圾值),然后读取了这些字段,并想知道为什么大部分都是垃圾?;-) 真的是“垃圾进,垃圾出”。 - DevSolar
1
问题在于小时、分钟和秒的值很高,我说得对吗?mktime()函数将把这些超出范围的值转换为相应的下一个更高单位的值(例如25小时-> 1小时,但+1天)。 - aQuip
3
在调用 strptime() 前,清除 time,否则其他字段中的随机值将通过 mktime() 调整为其正常范围,并影响年、月、日。 - chux - Reinstate Monica
mktime()会检查除了tm_ydaytm_wday之外的所有字段。因此,其他7个(或更多)字段的状态需要初始化。 - chux - Reinstate Monica
显示剩余2条评论
1个回答

13

mktime在将其所有参数转换为time_t之前对其进行规范化。由于小时、分钟和秒的值过大,因此这些值被转换为相应数量的天数,并把该值推远到未来。

在调用mktime之前,需要将tm结构体的其他重要属性(包括小时/分钟/秒)清零。如注释中所述,请将其初始化为零:tm time = {0}; (标记为C++,因此不需要前导的struct)。进一步注意,您可能希望将tm_isdst设置为-1,以便它尝试确定夏令时值而不是假定不使用夏令时(如果初始化为零)。


有没有比手动将所有值设置为零更聪明的方法?抱歉,我不太熟悉C语言。 - aQuip
1
“将小时/分钟/秒归零”是不够的。除了 tm_ydaytm_wday 之外,所有字段都需要初始化,包括 tm_isdst 和其他可能存在的字段。由于字段总数未定义,因此“对这些属性进行简单赋值”可能无法初始化所有字段,除非代码知道它们全部是什么。 - chux - Reinstate Monica
10
@aQuip struct tm time = {0}; - Weather Vane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接