mktime 仅处理 Clang 上的闰年?

mktime Only Handling Leap Years on Clang?

I proposed that marihikari use the standard functionality of mktime 而不是尝试实现他自己的公历系统。

我写这个函数来演示如何使用 mktime 来完成这个:

bool leap_year(int year) {
    tm bar = { 0, 0, 0, 29, 1, year - 1900 };

    mktime(&bar);

    return bar.tm_mday == 29 && bar.tm_mon == 1 && bar.tm_year == year - 1900;
}

用以下方法测试:

cout << "2000: " << leap_year(2000) << "\n2001: " << leap_year(2001) << "\n2004: " << leap_year(2004) << "\n1900: " << leap_year(1900) << "\n2100: " << leap_year(2100) << endl;

Clang 3.7.0 中产生了正确的结果:

2000: 1
2001: 0
2004: 1
1900: 0
2100: 0

gcc 5.1.0 中的结果不正确:

2000: 1
2001: 0
2004: 1
1900: 1
2100: 1

并且 Visual Studio 2015 中的结果不正确:

2000: 1
2001: 0
2004: 1
1900: 1
2100: 0

我认为这是 gcc 5.1.0 和 Visual Studio 2015 中的错误?

mktime:

Converts local calendar time to a time since epoch as a time_t object. time->tm_wday and time->tm_yday are ignored. The values in time are permitted to be outside their normal ranges.
...
If the conversion is successful, the time object is modified. All fields of time are updated to fit their proper ranges.

mktime 将 return:

Time since epoch as a time_t object on success or -1 if time cannot be represented as a time_t object.

但未指定实施必须做出哪些努力才能转换 tm。所以只要把时间转换成static_cast<time_t>(-1)就returned就满足了mktime的要求

意思是下面的函数will work on all platforms正确支持mktime:

bool leap_year(int year) {
    tm bar = { 0, 0, 0, 29, 1, year - 1900 };

    return static_cast<time_t>(-1) != mktime(&bar) && bar.tm_mday == 29 && bar.tm_mon == 1 && bar.tm_year == year - 1900;
}