为什么mktime()改变了我的tm结构的年份?

时间:2012-03-05 22:38:09

标签: c++ mktime

我读了两个字符串,包括年份,朱利安日(年),小时,分钟和观察。

我使用sscanf拉出相关变量:

sscanf(tide_str1.c_str(), "%d %d %d %d %Lf", &y1, &j1, &h1, &m1, &obs1);
sscanf(tide_str2.c_str(), "%d %d %d %d %Lf", &y2, &j2, &h2, &m2, &obs2);

对于此特定数据集,值为2011 083 23 22 1.1

然后我创建并填充一个tm结构,运行mktime,在两天之间的cout调用,它从083变为364。

int y1=2011, j1=83, h1=23, m1=22;
struct tm time_struct = {0, 0, 0, 0, 0, 0, 0, 0, 0}, *time_ptr = &time_struct;
time_t tv_min;
time_struct.tm_year = y1 - 1900;
time_struct.tm_yday = j1;
cout << time_struct.tm_yday << endl;
time_struct.tm_hour = h1;
time_struct.tm_min = m1;
time_struct.tm_isdst = -1;
cout << time_struct.tm_yday << endl;
tv_min = mktime(time_ptr);
cout << time_struct.tm_yday << endl;

为什么?是因为tm_mday和tm_mon设置为0?我最初尝试不将它全部初始化为零,但随后mktime返回-1。如果我只知道年,而不是月和月,我该怎么办?

1 个答案:

答案 0 :(得分:17)

mktime()正在做它应该做的事情。

引用C标准:

  

mktime 功能可转换故障时间,表示为   当地时间,在 timeptr 指向的结构中进入日历   时间值与返回值的编码相同   时间功能。 tm_wday 的原始值和   忽略结构的 tm_yday 组件,其他组件的原始值不限于范围   如上所述。成功完成后,值   结构的 tm_wday tm_yday 组件已正确设置,其他组件设置为代表   指定的日历时间,但其值被强制为范围   如上所述; tm_mday的最终值在 tm_mon 之前未设置   确定 tm_year

mktime()可以计算来自其他成员的tm_mdaytm_yday的值;它不是为了计算这些字段中其他成员的值而设计的。

但是,您可以执行的操作是使用超出范围的值初始化struct tm。例如,如果您希望tm_yday为200(一年中的第200天),则可以初始化代表1月200日的struct tm。然后mktime()会将其标准化为正确的日期,产生time_t值,然后您可以将其输入gmtime()localtime()

这是一个简单的例子:

#include <iostream>
#include <ctime>

int main()
{
    struct tm t = { 0 };
    t.tm_sec = t.tm_min = t.tm_hour = 0; // midnight
    t.tm_mon = 0;                        // January
    t.tm_year = 2012 - 1900;
    t.tm_isdst = -1;                     // unknown

    t.tm_mday = 200;                     // January 200th?

    time_t when = mktime(&t);
    const struct tm *norm = localtime(&when);   // Normalized time

    std::cout << "month=" << norm->tm_mon << ", day=" << norm->tm_mday << "\n";
    std::cout << "The 200th day of 2012 starts " << asctime(norm);
}

输出结果为:

month=6, day=18
The 200th day of 2012 starts Wed Jul 18 00:00:00 2012