全国咨询热线123456789
天数计算器
发布时间:2020-12-04 16:37浏览次数:
  • 天数计算器
  • 天数计算器

    一  完成的功能

    注意:此日历只能用于计算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 month = 10, int day = 4)
    	{
    		_year = year;
    		_month = month;
    		_day = day;
    	}
    	void printfMonth()//打印该日期所在月份日历
    	{
    		if (_year == 1582 && _month == 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&&_month == 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 (_month == 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 (_month == 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 (_month == 13)
    			{
    				_year++;
    				_month = 1;
    
    			}
    		}
    		return *this;
    	}
    		Date& operator-=(int day)
    		{
    			if (day < 0)//处理减一个负数的情况
    			{
    				return *this += -day;
    			}
    			_day -= day;
    			while (_day <= 0)
    			{
    				--_month;
    				if (_month == 0)
    				{
    					_month = 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 month = _month;
    			if ((_month == 1) || (_month == 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 ((month == 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;
    }
  • 天数计算器
  • -->