如何在 C 或 C++ 中比较日/月/年

How to compare day/month/year in C or C++?

本文关键字:比较 C++      更新时间:2023-10-16

我有一个程序,要求用户输入日期,然后它显示哪个是最近的 我这样做了

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

但是输出不太正确。

这是一个干净的方法:

#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对象的比较是按字典顺序进行的,因此如果date1小于 date20如果它们相同,则返回-1,如果date1大于 date2,则返回1

最好定义自己的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
}

您需要比这更复杂的检查:

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对我来说似乎是违反直觉的,但是我遵循了 OP 提供的语义。

此语句

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

测试三个条件中的任何一个是否为真。因此,如果第 1 年高于第 2 年,或者第 1 个月高于第 2 年。让我们就此打住。考虑

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

//你可以试试这个

int lday,lmonth,lyear;
int nday,nmonth,nyear;
int lhour,lminute;
int nhour,nminute;
sscanf(New_Time,"%d-%d",&nhour,&nminute); //reads the numbers
sscanf(Last_Time,"%d-%d",&lhour,&lminute); //from the string
sscanf(New_Date,"%d-%d-%d",&nday,&nmonth,&nyear);
sscanf(Last_Date,"%d-%d-%d",&lday,&lmonth,&lyear);
//cout << "Last date: " << lday << "-" << lmonth << "-" << lyear  <<endl;
//cout << "New date: " << nday << "-" << nmonth << "-" << nyear  <<endl;
if(nyear>lyear)
    return 0;
if(nyear==lyear) {
    if(nmonth > lmonth)
        return 0;
    if (nmonth == lmonth) {
        if(nday > lday)
            return 0;
        if (nday == lday) {
            if( nhour > lhour)
                return 0;
            if( nhour == lhour) {
                if(nminute>lminute) {
                    //cout << "new time >= last time" << endl <<endl;
                    return 0;
                }
                else return 1;
            }
            else return 1;
        }
        else return 1;
    }
    else return 1;
}
else return 1;
struct Day
{
    int value;
    explicit Day(int value)
    {
        this->value = value;
    }
};
struct Month
{
    int value;
    explicit Month(int value)
    {
        this->value = value;
    }
};
struct Year
{
    int value;
    explicit Year(int value)
    {
        this->value = value;
    }
};
class Date {
public:
    Date(Day newDay, Month newMonth, Year newYear)
    {
        _day = newDay.value;
        _month = newMonth.value;
        _year = newYear.value;
    }
    int GetYear() const {
        return _year;
    };
    int GetMonth() const {
        return _month;
    };
    int GetDay() const {
        return _day;
    };
private:
    int _year;
    int _month;
    int _day;
};    
bool operator < (const Date& lhs, const Date& rhs)
    {
        if (lhs.GetYear() == rhs.GetYear()) {
            if (lhs.GetMonth() == rhs.GetMonth()) {
                if (lhs.GetDay() == rhs.GetDay()) {
                    return false;
                }
    
                return lhs.GetDay() < rhs.GetDay();
            }
    
            return lhs.GetMonth() < rhs.GetMonth();
        }
    
        return lhs.GetYear() < rhs.GetYear();
    };