mktime 仅在 Clang 上处理闰年?

Posted

技术标签:

【中文标题】mktime 仅在 Clang 上处理闰年?【英文标题】:mktime Only Handling Leap Years on Clang? 【发布时间】:2015-11-02 12:16:14 【问题描述】:

在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 中的错误?

【问题讨论】:

【参考方案1】:

mktime:

将本地日历时间转换为自纪元以来的时间作为time_t 对象。 time-&gt;tm_wdaytime-&gt;tm_yday 被忽略。时间值允许超出正常范围。 ... 如果转换成功,则修改时间对象。所有时间字段都会更新以适应其适当的范围。

mktime 将返回:

自纪元以来的时间作为time_t 对象成功或-1 如果时间不能表示为time_t 对象。

没有具体说明实现必须做出哪些努力来转换tm。所以只要时间被转换static_cast&lt;time_t&gt;(-1)被返回,mktime的要求已经被满足了。

表示正确支持mktime的以下函数will work on all platforms:

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;

【讨论】:

以上是关于mktime 仅在 Clang 上处理闰年?的主要内容,如果未能解决你的问题,请参考以下文章

闰年用c语言怎么写?

C语言编程计算闰年

C语言如何判断是闰年,闰年判断条件

“千年虫问题”“2038年问题”什么是闰年

SZTUOJ 1015.闰年

c++ mktime和时间秒数的理解