装修知识

天数计算器

天数计算器

一  完成的功能

注意:此日历只能用于计算1982年10月15日以及以后的日期

1.日期+/-天数=返回日期(处理:1.如果+/-一个负的天数的情况 2.如果加之后,或减之后的日期非法)

2.两个日期之间间隔的天数,日期-日期=返回的天数(处理:返回的天数不能为负)

3.打印某年某月本月的日历(处理:1982年十月份)

二 功能分析

三 项目测试点:

功能测试:

(1)对输入日期合法性的测试--------------------边界值等价类

  1.年份是否合法

  2.月份是否合法

  3.天数是否合法

  4.年份月份天数结合是否合法

(2)对日期+天数=返回日期功能的测试

1.对于普通月份加的测试

2.测试平年/闰年2月份加减的测试

3.对于加一个负数,是否可以处理

4.如果加上一个数,日期小于1582年10月15,是否处理

(3)对日期-天数=返回日期功能的测试

1.对于普通月份减的测试

2.测试平年/闰年2月份减的测试

3.对于减一个负数,是否可以处理

4.如果减上一个数,日期小于1582年10月15,是否处理

(4)对于日期-日期=日期的功能性测试

 1.测试相减之后的日期是否合法

(5)对于输入日期,打印本月日历的功能性测试-------边界值/等价类

 1.测试输入1582年10月的日历打印

 2.测试大于1582年10月的日历打印

 3.测试小于1582年10月即非法日期日历打印的测试

界面测试:

(1)界面是否美观,清楚

(2)如果输入错误,错误提示字样是否正常输出

(3)如果输入错误,是要重新输入本次,还是要全部重新输入

四  项目源码

class Date { friend ostream& operator<<(ostream& os, const Date& d); friend istream& operator>>(istream& is, Date& d); public: Date(int year = 1582, int m 10, int day = 4) { _year = year; _m month; _day = day; } void printfMonth()//打印该日期所在月份日历 { if (_year == 1582 && _m= 10) { _PrintfMonthSpecial(); } else { _PrintfMonth(); } } //d+10 Date operator+(int day) { Date ret(*this); ret += day; return ret; } Date operator-(int day) { Date ret(*this); ret -= day; return ret; } int operator-(const Date& d) //日期-日期=返回天数 { int ret = DayNum( d); return ret; } bool operator==(const Date& d)const //只要实现> ==其他的都可以全部复用 { return _year == d._year&&_m= d._month&&_day == d._day; } bool operator >(const Date& d)const { if (_year > d._year) { return true; } else if (_year == d._year) { if (_month > d._month) { return true; } else if (_m= d._month) { if (_day > d._day) { return true; } } return false; } } bool operator<(const Date& d)const { return !(*this >= d); } bool operator >=(const Date& d)const { return *this > d || *this == d; } bool operator<=(const Date& d)const { return !(*this>d); } int judge() { if (_year < 1581 || _month<1 || _month>12 || _day<1 || _day>getmonthDay(_year, _month))//GetMonthDay不一定要写在前面,和C语言不一样,类是在类里面都会找 { return 1; } if (_year == 1582) { if (_month < 10 || _month >12) { return 1; } if (_m= 10 && (_day <15 || _day >= GetMonthDay(_year, _month))) { return 1; } } return 0; } private: Date& operator++()//前置 返回加加之后的值 { *this += 1; return *this; } //d++ d.opeartor++(&d,0) Date operator++(int i)//后制 { Date ret(*this); *this += 1; return ret; } int DayNum(const Date& d) { //int flag = 1; //Date* max=this; // Date* min= &d ; //if (*this < d) //{ // swap(max, min); // flag = -1; //} //int day = 0; //while (*min < *max)//自定义类型前置++好 //{ // ++(*min); // ++day; //} //return day*flag;//判断是正数,负数。 Date max = *this; Date min = d; if (*this < d) { max = d; min = *this; //flag = -1; } int day = 0; while (min < max) { ++min; ++day; } return day; } Date& operator+=(int day) { if (day<0)//处理加一个负数的情况 { return*this -= -day; } _day += day; while (_day > GetMonthDay(_year, _month)) { _day -= GetMonthDay(_year, _month); _month++; if (_m= 13) { _year++; _m 1; } } return *this; } Date& operator-=(int day) { if (day < 0)//处理减一个负数的情况 { return *this += -day; } _day -= day; while (_day <= 0) { --_month; if (_m= 0) { _m 12; --_year; } _day += GetMonthDay(_year, _month); } return *this; } void _PrintfMonth()//打印某个日期当月日历 { cout.width(5); cout << "日"; cout.width(5); cout << "一"; cout.width(5); cout << "二"; cout.width(5); cout << "三"; cout.width(5); cout << "四"; cout.width(5); cout << "五"; cout.width(5); cout << "六" << endl; int year = _year; int m _month; if ((_m= 1) || (_m= 2)) { year -= 1; month += 12; } //******************以下代码只考虑1582年10月4日之后的月历打印*************** //蔡勒公式:w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1 //w:星期; w对7取模得:0-星期日,1-星期一,2-星期二,3-星期三,4-星期四,5-星期五,6-星期六 //y:年(年数后两位数)c:世纪-1(年数前两位数)d:日 //m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算) int c = int(year / 100); int y = year - 100 * c; //计算当前月份第一天为星期几,d==1 int w = y + int(y / 4) + int(c / 4) - 2 * c + (26 * (month + 1) / 10) + 1 - 1;//***一定要注意带方括号取整数的算式,要加上int的强制类型转换 w = (w % 7 + 7) % 7;//处理负数的情况 for (int i = 0; i<w; i++)//处理第一行空白处 { cout.width(5); cout << " "; } for (int i = 0; i<7 - w; i++)//处理第一行日期 { cout.width(5); cout << i + 1; } cout << endl; int count = 0; for (int i = 7 - w; i< GetMonthDay(_year, _month); i++) { cout.width(5); cout << i + 1; count++; if ((count) / 7 == 1) { cout << endl; count = 0; } } cout << endl; } void _PrintfMonthSpecial() { cout.width(5); cout << "日"; cout.width(5); cout << "一"; cout.width(5); cout << "二"; cout.width(5); cout << "三"; cout.width(5); cout << "四"; cout.width(5); cout << "五"; cout.width(5); cout << "六" << endl; for (int i = 0; i<1; i++)//处理第一行空白处 { cout.width(5); cout << " "; } for (int i = 0; i < 6; i++)//处理第一行日期 { if (i >= 4) { cout.width(5); cout << i + 11; } else{ cout.width(5); cout << i + 1; } } cout << endl; int count = 0; for (int i = 16; i< GetMonthDay(_year, _month); i++) { cout.width(5); cout << i + 1; count++; if ((count) / 7 == 1) { cout << endl; count = 0; } } cout << endl; } int GetMonthDay(int year, int month) { static int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };//每次来都不动 int day = days[month]; if ((m= 2) && ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))//如果不是二月就不用走后面了 { day += 1; } return day; } private: int _year; int _month; int _day; }; ostream& operator<<(ostream& os, const Date& d) { os << d._year << "-" << d._month << "-" << d._day; return os; } istream& operator>>(istream&is, Date& d) { is >> d._year >> d._month >> d._day; return is; } void menu() { cout << "===================欢迎使用日期计算器==================="<<endl; cout << "============请根据如下提示输入相应编号选择功能=========="<<endl; cout << "================1.计算此天多少天之后的日期=============="<<endl; cout << "================2.计算此天多少天之前的日期=============="<< endl; cout << "================3.打印两个日期中间相隔天数=============="<<endl; cout << "================4.打印输入日期所在月的日历=============="<<endl; cout << "========================0.退出=========================="<<endl; } void test() { menu(); int n = 1; while (n) { end6: cout << "请按键选择相应的服务:"; cin >> n; switch (n) { case 1: { Date d1; int n = 0; end1: cout << "请输入开始日期:"; cin >> d1; int ret= d1.judge(); if (ret == 1) { cout << "非法日期,重新输入"<<endl; goto end1; } cout << "请输入天数:"; cin >> n; ret= (d1 + n).judge(); if (ret == 1) { cout << n << "天以后的日期是非法日期" << endl; break; } cout << n << "天以后的日期是:" << (d1 + n) << endl; cout << "请继续使用" << endl; break; } case 2: { Date d2; int n = 0; end2: cout << "请输入开始日期:"; cin >> d2; int ret= d2.judge(); if (ret == 1) { cout << "非法日期,重新输入" << endl; goto end2; } cout << "请输入天数:"; cin >> n; ret = (d2- n).judge();//判断减之后的日期是否合法 if (ret == 1) { cout << n << "天以前的日期是非法日期" << endl; break; } cout << n << "天以前的日期是:" << ret << endl; cout << "请继续使用" << endl; break; } case 3: { Date d3; Date d4; end3: cout << "请输入开始日期:"; cin >> d3; int ret= d3.judge(); if (ret == 1) { cout << "非法日期,重新输入" << endl; goto end3; } end4: cout << "请输入终止日期:"; cin >> d4; ret=d4.judge(); if (ret == 1) { cout << "非法日期,重新输入" << endl; goto end4; } cout << "两个日期之前相差:" << d4 - d3 << "天" << endl; cout << "请继续使用" << endl; break; } case 4: { Date d5; end5: cout << "请输入日期:"; cin >> d5; int ret = d5.judge(); if (ret == 1) { goto end5; } cout << "本月的日历为:" << endl; d5.PrintfMonth(); break; } case 0: break; default: cout << "输入错误!" << endl; goto end6; } } } int main()//测试用例 +一个负数 { test(); Date d; system("pause"); return 0; }