为什么mktime()会更改我的tm结构的年份

Why is mktime() changing the year day of my tm struct?

本文关键字:结构 tm 我的 mktime 为什么      更新时间:2023-10-16

我用两个字符串读取年份、儒略日(年-日)、小时、分钟和观测值。

我使用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。如果我只知道年份而不知道月份和月份,我应该做什么不同的事情?

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

引用C标准:

mktime函数转换故障时间,表示为本地时间,在timeptr指向日历的结构中时间值,其编码与时间函数。tm_wday和结构的tm_yday组件被忽略,其他组件的原始值不受范围限制如上所述。成功完成后结构的tm_wdaytm_yday组件设置适当,其他组件设置为表示指定的日历时间,但其值被强制到范围内如上所述;tm_mday的最终值直到tm_mon才设置和tm_ year

CCD_ 2可以计算来自其他成员的tm_mdaytm_yday的值;它的设计目的不是从这些字段中计算其他成员的值。

不过,您可以使用超出范围的值初始化struct tm。例如,如果希望tm_yday为200(一年中的第200天),则可以初始化代表1月第200天的struct tmmktime()会将其标准化为正确的日期,生成一个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