2015-11-02 54 views
1

this answer我建議marihikari使用標準功能mktime,而不是試圖實現自己的公曆系統。mktime只處理Clang的閏年?

我寫了這個功能演示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->tm_wdaytime->tm_yday被忽略。時間上的值被允許超出其正常範圍。
...
如果轉換成功,則修改時間對象。時間的所有領域都會更新以適合他們的適當範圍。

mktime將返回:

時間,因爲時代作爲成功time_t對象或-1,如果時間不能表示爲time_t對象。

然而,沒有指定實施必須做什麼努力來轉換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; 
}