tm_wday returns 0-6 范围外的大整数

tm_wday returns a large integer outside 0-6 range

c++ 中使用 tm 结构时,我得到 tm_wday 的值是大整数(例如 4199040,比预期的 0-6 范围大得多:)。为什么会这样?所有其他值如年、月等都是正确的。

我在之前的问题中看到工作日似乎计算错误,即由于时区差异等原因,0-6 范围内的值与预期值不同。但我很困惑为什么我会得到这么大的数字?它似乎也不是内存位置(不是十六进制格式的数字)。

#include <stdio.h>
#include <iostream>
#include <time.h>


struct tm get_time(std::string timestamp_string = "2019.08.16D11:00:00"){

    struct tm tm;
    int hh, mm;
    int MM, DD, YY;
    float ss;
    const char * timestamp = timestamp_string.c_str();
    if (sscanf(timestamp,"%d.%d.%dD%d:%d:%f", &YY,&MM, &DD,&hh, &mm,&ss) != 6) std::cout<<"oops";

    tm.tm_year = YY - 1900;  // Years from 1900
    tm.tm_mon = MM - 1; // Months form January
    tm.tm_mday = DD;
    tm.tm_hour = hh;
    tm.tm_min = mm;
    tm.tm_sec = ss;
    tm.tm_isdst = 0;
    return tm;

}

int main(){
    struct tm tm = get_time("2019.08.16D11:00:00");
    std::cout<<"Year is: "<<tm.tm_year<<std::endl; //119 - is correct
    std::cout<<"Month since Jan is: "<<tm.tm_mon<<std::endl; //7 - is correct
    std::cout<<"Weekday is: "<<tm.tm_wday<<std::endl;//4199040- why is this so large?

    return 0;
}

环顾四周,预计在定义 tm 结构后,您 运行 函数 mktime() 引用实例以更新派生值比如tm_wday。所以固定的main()函数应该是:

int main(){
    struct tm tm = get_time("2019.08.16D11:00:00");
    mktime(&tm); //needs to be called to update derived values such as tm_wday
    std::cout<<"Year is: "<<tm.tm_year<<std::endl; //119 - is correct
    std::cout<<"Month since Jan is: "<<tm.tm_mon<<std::endl; //7 - is correct
    std::cout<<"Weekday is: "<<tm.tm_wday<<std::endl;//shows 5 now - is correct
    return 0;
}

为什么它应该是任何其他值?

您从未将其设置为任何内容。

因此,它保留其初始值,即 未指定,因为您从未初始化 tm

因此,不仅仅是 "a large integer":由于试图读取这个未指定的值,您的整个程序都有未定义的行为。


如果您希望它自动设置为您输入的值的适当工作日索引,那不是它的工作原理。 tm 只是值的集合,不是函数。

但是,您可以调用 mktime 来完成您需要的操作:

The mktime() function modifies the fields of the tm structure as follows: tm_wday and tm_yday are set to values determined from the contents of the other fields; if structure members are outside their valid interval, they will be normalized (so that, for example, 40 October is changed into 9 November); tm_isdst is set (regardless of its initial value) to a positive value or to 0, respectively, to indicate whether DST is or is not in effect at the specified time. Calling mktime() also sets the external variable tzname with information about the current timezone.

(ref)