2013-12-21 50 views
2

我有一個程序,要求用戶輸入日期,然後顯示哪一個是最近我已經做了這樣的如何在C或C++中比較日/月/年?

if (year1>year2 || month1>month2 || day1>day2) 
    return -1; 

if (year1<year2 || month1<month2 || day1<day2) 
    return +1; 

但輸出是不太正確的。

+2

對,你的邏輯錯了,這與C++無關。只是想一想。你需要的是按年份,月份和日期的順序進行字典對比。 – juanchopanza

+0

你有沒有嘗試寫出幾個樣本日期,並嘗試自己的邏輯?比較2013-12-31,2014-01-01。 – kfsone

回答

2

你需要一個更復雜的檢查比:

if (year1 > year2) 
    return -1; 
else if (year1 < year2) 
    return +1; 

if (month1 > month2) 
    return -1; 
else if (month1 < month2) 
    return +1; 

if (day1 > day2) 
    return -1; 
else if (day1 < day2) 
    return +1; 

return 0; 

注:第一返回-1是大於第二似乎有點違背intuititive給我,但我都遵循由OP提供的語義。

+0

可能是一個好主意,可以用單個比較運算符來表示整個事物,可能是運算符<。 – kfsone

+1

@kfsone同意,但是OP沒有提供足夠的測試環境。所以我提供了一個* drop-in *替換。 – trojanfoe

+0

很高興您還爲日期相同的情況提供了回報。 – Rob

8

這裏有一個乾淨的方式做到這一點:

#include <tuple> // for std::tie 

auto date1 = std::tie(year1, month1, day1); 
auto date2 = std::tie(year2, month2, day2); 

if (date1 == date2) 
    return 0; 

return (date1 < date2) ? -1 : 1; 

std::tie對象的比較是辭書,那麼這將返回-1如果date1小於date20如果它們是相同的,並且1如果date1是大於date2

您可能最好定義自己的date類型(或使用boost::datetime)。

struct Date 
{ 
    unsigned year; 
    unsigned month; 
    unsigned day; 
}; 

bool operator<(const Date& lhs, const Date& rhs) 
{ 
    return std::tie(lhs.year, lhs.month, lhs.day) < 
     std::tie(rhs.year, rhs.month, rhs.day); 
} 

bool operator>(const Date& lhs, const Date& rhs) { .... } 

bool operator==(const Date& lhs, const Date& rhs) { .... } 

int date_cmp(const Date& lhs, const Date& rhs) 
{ 
    // use operators above to return -1, 0, 1 accordingly 
} 
1

本聲明

if (year1>year2 || month1>month2 || day1>day2) 
    return -1; 

測試,如果的三個條件中的任何一個是真的。所以,如果year1高於2年,或者month1高於month2。讓我們停下來。考慮

year1 = 2013, month1 = 12, day1 = 31; 
year2 = 2014, month2 = 1, day1 = 1; 

我們知道,事實上,YEAR2是一個較高的值,但發生的事情是

is year1 > year2? no 
ok, but is month1 > month2? yes 

這使它看起來像第一年是一個較高的值,但它不是,它只是較高的月份值。

隨着您對C++的深入研究,您會發現嘗試採用一種慣例,即使您使用單個運算符(<或>)進行所有比較,當您到達與您一起工作的位置時運營商你會明白爲什麼。

if (year2 < year1) 
    return 1; 
// we reach this line when year1 <= year2 
if (year1 < year2) // elimnate the < case 
    return -1; 

// having eliminated both non-matches, 
// we know that by reaching point that both 
// dates have the same year. Now repeat for 
// the month value. 
if (month2 < month1) 
    return 1; 
if (month1 < month2) 
    return -1; 

// year and month must be the same, repeat for day. 
if (day2 < day1) 
    return 1; 
if (day1 < day2) 
    return -1; 
return 0; // exact match