日期类的实现

在学习C++类的时候,日期类是最基础也是最重要的一个类。简单的日期类并不复杂,但在实现的过程中主要会涉及一些C++的基本成员函数。这个代码的难度主要在于如何判断日期类的合法性,比如月份如果大于12,天数也要合法,比如二月不能闰年不能超过30天,平年28天。在自增和自减的时候,也要考虑到年份、月份和天数的变化。

下面给出类的定义:

class Date
{
    friend ostream& operator <<(ostream& _cout, const Date& date);
    friend istream& operator >>(istream& _cin, Date& date);
public:
    Date(int year = 1990, int month = 1, int day = 1);
    Date(const Date& date);
    Date& operator=(const Date& date);
    Date& operator++();
    Date operator++(int);
    Date operator+(int day);
    Date operator-(int day);
    Date& operator--();
    Date operator--(int);
    bool operator>(const Date& date);
    bool operator<(const Date& date);
    bool operator==(const Date& date);
    bool operator!=(const Date& date);
    bool operator>=(const Date& date);
    bool operator<=(const Date& date);

private:
    bool IsLeapYear(int year)
    {
        return((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0));
    }

    int GetMonthDay(int year, int month)
    {
        assert(month > 0 && month < 13);
        static int days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int day = days[month];
        if ((month == 2) && (IsLeapYear(year)))
        {
            day += 1;
        }
        return day;
    }

private:
    int _year;
    int _month;
    int _day;
};

在写这个代码的过程中,有两个地方是我考虑得比较多的地方。在考虑到自增的问题时,Date& operator++()和Date operator+(int day)有相似的地方,在写代码的时候,我是先写的++。代码如下:

Date& Date::operator++()
{
    int days = GetMonthDay(_year, _month);
    if (_day < days)
    {
        _day++;
    }
    else if (_day == days)
    {
        _day = 1;
        if (_month < 12)
        {
            _month++;
        }
        else
        {
            _month = 1;
            _year++;
        }
    }
    else
    {
        assert(false);
    }
    return *this;
}

在写到Date operator+(int day)时,我是直接在日期类直接加上来的。比如,今天是2017年1月16日,在加上30天,也就是2017年1月46日,当然46日是不符合日期合法性的。1月一共31天,那么用46-31天,即2017年2月15日,15日符合2月的日期合法性,即是所求的日期。代码实现如下:

Date Date::operator +(int day)
{
    Date tmp = *this;
    if (day<0)
    {
        day = -day;
        return tmp - day;
    }
    tmp._day += day;
    while (tmp._day>GetMonthDay(tmp._year,tmp._month))
    {
        tmp._day -= GetMonthDay(tmp._year, tmp._month);
        if (tmp._month < 12)
            tmp._month++;
        else
        {
            tmp._year++;
        }
    }
    return tmp;
}

然而写完后我发现,++可以通过+1来实现也就是说:

Date& Date::operator++()
{
    Date tmp = *this;
    (*this) =(*this) + 1;
    return *this;
}

加法和减法是一样的,这里就不赘余了。有兴趣的同学,可以按照步骤去实现一下。下面给出所有的功能代码:

ostream& operator <<(ostream& _cout, const Date& date)
{
    _cout << date._year << "/" << date._month << "/" << date._day << endl;
    return _cout;
}

istream& operator >>(istream& _cin, Date& date)
{
    _cin >> date._year >> date._month >> date._day;
    return _cin;
}

Date::Date(int year, int month, int day)
{
    if (year > 0
        && ((month > 0) && (month<13))
        && ((day>0) && (day <= GetMonthDay(year, month))))
    {
        _year = year;
        _month = month;
        _day = day;
    }

    else
    {
        cout << "the date is illegal!" << endl;
    }
}

Date::Date(const Date& date)
:_year(date._year)
, _month(date._month)
, _day(date._day)
{}

Date& Date::operator=(const Date& date)
{
    if (this != &date)
    {
        _year = date._year;
        _month = date._month;
        _day = date._day;
    }
    return *this;
}

Date& Date::operator++()
{
    Date tmp = *this;
    (*this) =(*this) + 1;
    return *this;
}

Date Date::operator++(int)
{
    Date tmp = *this;
    ++(*this);
    return tmp;
}

Date Date::operator +(int day)
{
    Date tmp = *this;
    if (day<0)
    {
        day = -day;
        return tmp - day;
    }
    tmp._day += day;
    while (tmp._day>GetMonthDay(tmp._year,tmp._month))
    {
        tmp._day -= GetMonthDay(tmp._year, tmp._month);
        if (tmp._month < 12)
            tmp._month++;
        else
        {
            tmp._year++;
        }
    }
    return tmp;
}

Date Date::operator-(int day)
{
    Date tmp = *this;
    tmp._day -= day;
    while (tmp._day <=0)
    {
        if (tmp._month == 1)
        {
            tmp._year--;
            tmp._month = 12;
        }
        else
        {
            tmp._month--;
        }

        tmp._day += GetMonthDay(tmp._year, tmp._month);
    }
    return tmp;
}

Date& Date::operator--()
{
    (*this) = (*this) - 1;
    return *this;
}

Date Date::operator--(int)
{
    Date tmp = *this;
    (*this) = (*this) - 1;
    return tmp;
}

bool  Date::operator>(const Date& date)
{
    if ((_year > date._year)
        || ((_year == date._year) &&( _month > date._month) )
        || ((_year == date._year) && (_month == date._month) && (_day > date._day)))
        return true;
    else
        return false;
}

bool Date::operator<(const Date& date)
{
    if ((_year < date._year)
        || ((_year == date._year) && (_month < date._month))
        || ((_year == date._year) && (_month == date._month) || (_day < date._day)))
        return true;
    else
        return false;
}

bool Date::operator==(const Date& date)
{
    return ((_year == date._year) && (_month == date._month) && (_day == date._day));
}

bool Date::operator!=(const Date& date)
{
    return !(*this == date);
}

bool Date::operator>=(const Date& date)
{
    if ((*this) < date)
        return false;
    else
        return true;
}

bool Date::operator<=(const Date& date)
{
    if ((*this) > date)
        return false;
    else
        return true;
}
void Test()  
{
    Date d1(2017, 1, 23);
    Date d2(2017, 1, 23);
    cout << ++d1;
    cout << d1++;
    cout << d1 + 30;
    cout << d1 - 207 ;
    cout << --d1;
    cout << d1--;
    cout << (d1 > d2) << endl;
    cout << (d1 < d2) << endl;
    cout << (d1 == d2) << endl;
    cout << (d1 != d2) << endl;
    cout << (d1 <= d2) << endl;
    cout << (d1 >= d2) << endl;
}

int main()
{
    Test();
    system("pause");
}

整个日期类的代码实现就这么多,在写代码的过程中还是难免会遇到一些奇奇怪怪的问题,比如在写最后几个函数时,函数逻辑没一点问题,但是测试函数写得有问题,所以整个程序也就有点问题。总而言之,在写代码的时候要多考虑一些,把能简化的地方尽量简化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值