日期计算器

一  完成的功能

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

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

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

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

二 功能分析

日期计算器_第1张图片

三 项目测试点:

功能测试:

(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= 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 << "===================欢迎使用日期计算器==================="<> n;
		switch (n)
		{
		case 1:
		{
				  Date d1;
				  int n = 0;
			     end1:
				  cout << "请输入开始日期:";
				  cin >> d1;
				 int ret= d1.judge();
				 if (ret == 1)
				 {
					 cout << "非法日期,重新输入"<> 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;
}


 

你可能感兴趣的:(c语言)