在this answer中,我建议marihikari使用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中的一个错误?
答案 0 :(得分:1)
将本地日历时间转换为自纪元以来的时间
time_t
对象。time->tm_wday
和time->tm_yday
会被忽略。允许的时间值超出其正常范围 ...
如果转换成功,则修改时间对象。所有时间段都会更新,以适应其适当的范围。
mktime
将返回:
自纪元作为成功的
time_t
对象的时间,如果时间不能表示为time_t
对象,则为-1。
但是,未指定实现必须为转换tm
做出哪些努力。因此,只要转换时间或 static_cast<time_t>(-1)
,就会填写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;
}