【问题标题】:mktime Only Handling Leap Years on Clang?mktime 仅在 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 中的错误?

【问题讨论】:

    标签: c++ visual-studio gcc clang mktime


    【解决方案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;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-07-16
      • 1970-01-01
      • 2012-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多