欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

日期计算器

程序员文章站 2024-02-27 13:02:51
...

一  完成的功能

注意:此日历只能用于计算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;
}