C++日期的进位运算源代码
需求分析
自定义一个简单的日期类DateType,它具有数据成员y、m、d,用来表示当前日期的年、月、日。而后设计该类欲实现(完成)的功能,进而设计出相应的类成员函数。
例如,下面给出的“雏形”可用来实现对天的增加,比较两个日期是否相等,以及对日期的输出等操作。请完成各类成员函数,并编制主函数,说明DateType类对象,对定义的各成员函数进行调用,以验证它们的正确性。
class DateType { //自定义的日期类DateType
int y,m,d; //数据成员,表示当前日期的年、月、日
public:
DateType(int y0=1, int m0=1, int d0=1);
//构造函数,设定年、月、日;并设置参数默认值
void incrementDay(); //增加1天
bool equal(DateType dt2); //判断二日期是否相等
void printDate(); //屏幕输出日期对象的有关数据(年、月、日)
};
注意,当对日期增加1天后,也会涉及所谓的“进位”问题:首先算出本“日”所在的月份具有的天数N,若加1之后的“日”数值超过所在的月份具有的天数N时,“进位”到月,而月份若超过12时还要“进位”到年。
思考:可对该类增加你所考虑到的其他功能,如,对日期进行输入,计算二日期的间隔天数,计算某日期为星期几,打印对象当前数据的y年m月的月历,一次增加若干天,对两个日期进行其他比较运算等。
7.2概要设计
定义一个日期类,其中包括年月日。然后实现日期加一的功能,有可能“进位”。
7.3详细设计与编码
代码见上传实验
流程图如下:main
其他函数流程图
7.4调试分析
从2008年1月1日开始计时,输入2008 12 29
7.5用户使用说明
运行程序,用户可以根据提示,输入随便一个日期,系统会自动计算日历及所在日的月历。
7.6本程序是我迄今为止编过的最复杂的程序,有很多东西不懂,更不熟悉,不懂就问,通过和同学的学习,最后还是做了出来
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
class DateType
{
public:
DateType(); //默认构造函数
DateType(int y0,int m0,int d0); //带参构造函数
void incrementDay(); //增加一天
bool equal(DateType dt2) const; //判断两个日期是否相等
void printDate() const; //屏幕输出日期对象的有关数据(年、月、日)
void inputDate(); //输入一个日期
int interval(DateType dt2) const; //计算两个日期之间间隔的天数
int dayOfWeek() const; //计算一个日期为星期几
int dayNum() const; //计算当前日期距0年1月1日的天数
bool isLeap(int year) const; //是否是闰年
void printCalendar() const; //打印对象当前数据的y年m月的月历
private:
int y,m,d; ////数据成员,表示当前日期的年、月、日
};
DateType::DateType() //默认构造函数
{
y=0;
m=0;
d=0;
}
DateType::DateType(int y0,int m0,int d0) //带参构造函数
{
y=y0;
m=m0;
d=d0;
}
void DateType::inputDate() ////输入一个日期
{
cout <<"请输入一个日期(数字之间用空格隔开,形如 2008 8 21):";
cin >>this->y>>this->m>>this->d;
}
void DateType::incrementDay() //增加一天
{
int dayNum; //本月所在月份的天数
switch(m)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: dayNum=31;break;
case 2: dayNum=28;break;
case 4:
case 6:
case 9:
case 11: dayNum=30;break;
}
if((y%4==0 && y%100!=0) || y%400==0) //是瑞年且是2月份,则天数加1
if(m==2)
dayNum++;
d++;
if(d>dayNum)
{
d=1;
m++;
if(m>12)
{
m=1;
y++;
}
}
}
bool DateType::equal(DateType dt2) const //判断两个日期是否相等
{
if(y==dt2.y && m==dt2.m && d==dt2.d)
return true;
else
return false;
}
void DateType::printDate() const //屏幕输出日期对象的有关数据(年、月、日)
{
cout <<y<<"年";
if(m<10)
cout <<"0";
cout <<m<<"月";
if(d<10)
cout <<"0";
cout <<d<<"日"<<endl;
}
bool DateType::isLeap(int year) const //是否是闰年
{
if((year%4==0 && year%100!=0) || year%400==0)
return true;
else
return false;
}
int DateType::dayNum() const //计算当前日期距0年1月1日的天数
{
int leapNum=0; //累计从0年到y年(不包括y年)共有多少闰年
int numDay=0; //this指向的对象表示的日期距0年1月1日的天数
for(int i=0;i<y;i++) //年
if(isLeap(i))
leapNum++;
numDay=365*y+leapNum;
for(i=0;i<m-1;i++) //月
{
if(i==1)
{
if(isLeap(y))
numDay+=29;
else
numDay+=28;
}
else if(i==0 || i==2 || i==4 || i==6 || i==7 || i==9 || i==11)
numDay+=31;
else
numDay+=30;
}
numDay+=d-1; //日
return numDay;
}
int DateType::interval(DateType dt2) const //计算两个日期之间间隔的天数
{
int numDay1,numDay2; //numDay1,numDay2分别表示this指向的对象和dt2表示的日期距0年1月1日的天数
//二者的差值的绝对值就是要求的间隔数
numDay1=dayNum();
numDay2=dt2.dayNum();
return fabs(numDay1-numDay2);
}
int DateType::dayOfWeek() const //计算一个日期为星期几
{/*算法如下:
基姆拉尔森计算公式
W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
在公式中d表示日期中的日数,m表示月份数,y表示年数。
注意:在公式中有个与其他公式不同的地方:
把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。
*/
int yy=y,mm=m,dd=d; //保存类的成员变量,防止对其的修改
if(mm==1 || mm==2)
{
mm=mm+12;
yy--;
}
int week;
week=(dd+2*mm+3*(mm+1)/5+yy+yy/4-yy/100+yy/400)%7+1;
string weekstr="";
switch(week)
{
case 1: weekstr="星期一";break;
case 2: weekstr="星期二";break;
case 3: weekstr="星期三";break;
case 4: weekstr="星期四";break;
case 5: weekstr="星期五";break;
case 6: weekstr="星期辣";break;
case 7: weekstr="星期日";break;
}
cout <<weekstr;
return week;
}
void DateType::printCalendar() const //打印对象当前数据的y年m月的月历
{
cout <<"S\t"<<"M\t"<<"T\t"<<"W\t"<<"T\t"<<"F\t"<<"S\t"<<endl;
int total=365*y;
for(int i=0;i<y;i++) //年
if(isLeap(i))
total++;
for(i=0;i<m-1;i++) //月
{
if(i==1)
{
if(isLeap(y))
total+=29;
else
total+=28;
}
else if(i==0 || i==2 || i==4 || i==6 || i==7 || i==9 || i==11)
total+=31;
else
total+=30;
}
int week=total%7; //当月的1号是星期几
if(week==0)
week=7;
week-=1; //0~星期日,1~星期一 …… 6~星期辣
int monthDay; //当前月份有多少天
switch(m)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: monthDay=31;break;
case 2: monthDay=28;break;
case 4:
case 6:
case 9:
case 11: monthDay=30;break;
}
if((y%4==0 && y%100!=0) || y%400==0) //是瑞年且是2月份,则天数加1
if(m==2)
monthDay++;
int flag=0; //0~6 ,用于控制每行打印7个日期
for(int j=0;j<week;j++)
{
cout <<"\t"; //打印月初开头的空格
flag++;
}
for(j=1;j<=monthDay;j++)
{
cout <<j<<"\t";
if(flag++==6)
{
cout <<endl;
flag=0;
}
}
cout <<endl<<endl;
}
int main()
{
DateType p1(2008,1,1);
cout <<"第一个日期为:";
p1.printDate();
DateType p2;
p2.inputDate();
原文请找腾讯752018766辣,文-论'文.网http://www.751com.cn p2.incrementDay();
cout <<"\n调用incrementDay()后第二个日期为:";
p2.printDate();
//判断是星期几
p1.printDate();
cout <<"是 ";
p1.dayOfWeek();
cout <<endl;
p2.printDate();
cout <<"是 ";
p2.dayOfWeek();
cout <<endl;
cout<<endl;
p1.printDate();
cout <<"和"<<endl;
p2.printDate();
cout <<"之间间隔的天数为: "<<p1.interval(p2)<<endl;
cout <<"两个日期所在月的月历分别为"<<endl;
p1.printCalendar();
p2.printCalendar(); return 0;}