mktime只处理Clang的闰年?

时间:2015-11-02 12:16:15

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

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 个答案:

答案 0 :(得分:1)

mktime

  

将本地日历时间转换为自纪元以来的时间time_t对象。 time->tm_wdaytime->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;
}