mktime Only Handling Leap Years on Clang?

元气小坏坏 提交于 2019-12-24 15:21:29

问题


In this answer I proposed that marihikari use the standard functionality of mktime rather than trying to implement his own Gregorian calendar system.

I wrote this function to demonstrate how mktime could be used to accomplish this:

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;
}

Testing this with:

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

Yielded the correct result in Clang 3.7.0:

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

But an incorrect result in gcc 5.1.0:

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

And an incorrect result in Visual Studio 2015:

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

I assume this is a bug in gcc 5.1.0 and Visual Studio 2015?


回答1:


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 will return:

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

It is not specified however what efforts the implementation must make to convert the tm. So as long as the time is converted or static_cast<time_t>(-1) is returned the requirements for mktime have been filled.

Meaning that the following function will work on all platforms that correctly support 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;
}


来源:https://stackoverflow.com/questions/33477379/mktime-only-handling-leap-years-on-clang

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!