日期类功能大全

名称:日期类
功能:对按格式如(2000,1,1)的日期,进行合法性判断;闰年判断;判断两个日期是否是同一天;日期的输入输出;判断某个日期是这一年中的第几天;对任一日期增加指定年数、指定月数,并返回对应日期;判断任一日期是星期几
来源:c++程序设计原理与应用9.8,做了一定的内容修改和添加
日期:2017.8.17
Chrono.h

namespace Chrono {
    enum class Month
    {
        jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec
    };
    enum class Day {
        sunday,monday,tuesday,wednesday,thursday,friday,saturday
    };
    class Date {
    public:
        class Invalid { };               //作为抛出异常
        Date(int y, Month m, int d);    //检查日期合法性并初始化
        Date();                         //默认拷贝操作是可用的

        //不改变对象的操作
        int day()const { return d; }
        Month month()const { return m; }
        int year()const { return y; }

        //改变对象的操作
        void add_day(int n);
        void add_month(int n);
        void add_year(int n);
    private:
        int y;
        Month m;
        int d;
    };

    bool is_date(int y, Month m, int d);//当日期合法时返回true
    bool leapyear(int y);               //当y是闰年时返回true
    bool operator!=(const Date& a, const Date& b);
    bool operator==(const Date& a, const Date& b);
    ostream& operator<<(ostream& os, const Date& d);
    istream& operator>>(istream& os, const Date& d);
    int daynum(const Date& d);
}

Chrono.cpp

#include "std_lib_facilities.h"
#include "Chrono.h"
using namespace Chrono;
namespace Chrono {
    //成员函数的定义
    Date::Date(int yy, Month mm, int dd) :y{ yy }, m{ mm }, d{dd} {
        if (!is_date(yy, mm, dd)) throw Invalid{};
    }
    const Date& default_date() {
        static Date dd{ 2001,Month::jan,1 };
        return dd;
    }
    Date::Date():y{ default_date().year()}, m{ default_date().month()},d{ default_date().day()}{ }

    void Date::add_day(int n) {
        //...
    }
    void Date::add_month(int n) {
        int rem = ((int)m + n)%12;
        int integer = ((int)m + n) / 12;

        if (rem == 0) {
            m = Month::dec;
            add_year(integer-1);
        }
        else {
            m = Month(rem);
            add_year(integer);
        }
    }
    void Date::add_year(int n) {
        if (m == Month::feb&&d == 29 && !leapyear(y + n)) {  //小心闰年
            m = Month::mar;                                  //用3月1日代替2月29日
            d = 1;
        }
        y += n;
    }
    //辅助函数
    int daynum(const Date& d) {        //某个日期是这一年中的多少天,返回这个数字
        int mon[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
        int sum = 0;
        if (leapyear(d.year())) {
            mon[1] = 29;
            if (d.month() == Month::jan) {
                sum += d.day();
            }
            else {
                for (int i = 0; i<int(d.month()) - 1; i++) sum += mon[i];
                sum += d.day();
            }
        }
        else {
            if (d.month() == Month::jan) {
                sum += d.day();
            }
            else {
                for (int i = 0; i<int(d.month()) - 1; i++) sum += mon[i];
                sum += d.day();
            }
        }
        return sum;
    }
    bool is_date(int y, Month m, int d)
    {
        //假设y是合法的

        if(d <= 0) return false;
        if (m < Month::jan || Month::dec < m) return false;

        int days_in_month = 31;
        switch (m)
        {
        case Month::feb:
            days_in_month = (leapyear(y)) ? 29 : 28;
            break;
        case Month::apr:case Month::jun:case Month::sep:case Month::nov:
            days_in_month = 30;
            break;
        }
        if (days_in_month < d)return false;
        return true;
    }
    bool leapyear(int y)//闰年:能被4整除且不能被100整除或者能被400整除的年份
    {
        return ( y%4 == 0 && y%100 != 0 || y%400 == 0 );
    }
    bool operator==(const Date& a, const Date&b) {
        return a.year() == b.year() && a.month() == b.month() && a.day() == b.day();
    }
    bool operator!=(const Date& a, const Date&b) {
        return !(a == b);
    }
    ostream& operator<<(ostream& os, const Date& d) {
        return os << '(' << d.year() << ',' << (int)d.month() << ',' << d.day() << ')';
    }
    istream& operator>>(istream& is, Date& dd) {
        int y, m, d;
        char ch1, ch2, ch3, ch4;
        is >> ch1 >> y >> ch2 >> m >> ch3 >> d >> ch4;
        if (!is) return is;
        if (ch1 != '(' || ch2 != ',' || ch3 != ',' || ch4 != ')') {
            is.clear(ios_base::failbit);                                //设置failbit
            return is;
        }
        dd = Date(y, Month(m), d);
        return is;
    }
    ostream& operator<<(ostream& os, const Day& d) {
        switch (d)
        {
        case Day::monday: return os << "monday"; 
        case Day::tuesday: return os << "tuesday"; ;
        case Day::wednesday: return os << "wednesday"; 
        case Day::thursday: return os << "thursday"; 
        case Day::friday: return os << "friday" ; 
        case Day::saturday: return os << "saturday"; 
        case Day::sunday: return os << "sunday"; 
        }

    }
    Day day_of_week(const Date& d) {        
        int y = d.year();
        int m = (int)(d.month());
        int dd = d.day();
        if (d.month() == Month::jan || d.month() == Month::feb) {
            m += 12;
            y--;
        }
        int iWeek = (dd + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;
        switch (iWeek)
        {
        case 0: return Day::monday; 
        case 1: return Day::tuesday; 
        case 2: return Day::wednesday; 
        case 3: return Day::thursday; 
        case 4: return Day::friday; 
        case 5: return Day::saturday; 
        case 6: return Day::sunday; 
        }

    }
}
int main() {
    cout << "请输入一个日期" << endl;
    Date date;

    cin >> date;
    if (is_date(date.year(), date.month(), date.day())) {
        cout << "日期合法" << endl;
    }
    else {
        cout << "日期非法" << endl;
        return 1;
    }
    //date.add_year(1);
    //cout << date << endl;
    date.add_month(12);
    cout << date << "今天是:"<<day_of_week(date)<<endl;
    Date dd(date);
    Date d3;
    d3=dd;
    cout <<"今天是今年中的第"<< daynum(dd)<<"天!"<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值