您的位置:首页 > 其它

关于日期的一些运算

2017-03-21 00:24 309 查看
有给是日期加加上天数求新日期的,也有加月份数、加年数求新日期。

本题比较综合,写了好一会的代码。。。主要是会有情况遗漏。。话不多说,贴题题ac代码。

题目如下:

1: 日期结构体操作

作者: Turbo时间限制: 1S章节: OO:其它

问题描述 :

实验目的:巩固结构体类型知识,为学习类的声明打基础。

实验内容:声明一个结构体类型Date,包括年月日,即一个日期类型的结构体。

 

设计一个程序,完成以下对日期的操作,包括以下函数:

Date AddDay(Date d, int days):对日期增加days天数,然后返回得到的日期

Date AddMonth(Date d, int months):对日期增加months月数,然后返回得到的日期

Date AddYear(Date d, int years):对日期增加years年数,然后返回得到的日期

int Subtract(Date d1, Date d2):用d1-d2,计算它们相距的天数,作为函数值返回

 

GetWeekDay:输入参数为Date类型,返回该日期是星期几。星期几最好用枚举表示,也就是返回一个枚举类型的值。本函数可选做,测试数据不包含本函数。

 

程序输出相应计算结果。

 

请使用以下main函数:

int main()
{
char WeekDayNames[][15]={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday","Friday", "Saturday"};
int op;
while(cin>>op)
{
Date d1, d2;
int n;
DayName w;
switch(op)
{
case 1: //add days
cin>>d1.year>>d1.month>>d1.day>>n;
d2=AddDay(d1, n);
cout<<d2.year<<" "<<d2.month <<" " <<d2.day<<endl;
break;
case 2:
cin>>d1.year>>d1.month>>d1.day>>n;
d2=AddMonth(d1, n);
cout<<d2.year<<" "<<d2.month <<" " <<d2.day<<endl;
break;
case 3:
cin>>d1.year>>d1.month>>d1.day>>n;
d2=AddYear(d1, n);
cout<<d2.year<<" "<<d2.month <<" " <<d2.day<<endl;
break;
case 4:
cin>>d1.year>>d1.month>>d1.day>>d2.year>>d2.month>>d2.day;
n=Subtract(d1, d2);
cout<<n<<endl;
break;
case 5:
cin>>d1.year>>d1.month>>d1.day;
w=GetWeekDay(d1);
cout<<WeekDayNames[w]<<endl;
break;
}
}
}



输入说明 :
程序包含多组输入,每组测试数据包含两行,第一行用一个整数(1到5)指定需要完成的操作,含义如下:

1:AddDay

2:AddMonth

3:AddYear

4:Subtract

5:GetWeekDay(测试数据中不包含本输入)

第二行为该操作需要的数据。

比如输入:

1

2016 1 1 31

表示将进行AddDay操作,输入日期为2016年1月1日,加31天。

程序输出结果日期,按年月日格式输出,中间以一个空格分隔。

输出说明 :

程序输出相应计算结果。

对于AddDay、AddMonth、AddYear三种操作,输出结果日期,按年月日格式输出,中间以一个空格分隔。

对于Subtract,结果仅输出一个整数,表示相距的天数。

每组输出占一行,行首与行尾无多余空格,所有地方无多余空行。

输入:

1

2000 2 28 20

2

2000 1 31 3

3

2000 1 31 1

4

2016 3 8 2016 2 8

4

2016 1 8 2016 2 8

4

2015 3 8 2016 3 8

5

2017 03 20

对应输出:

2000 3 19

2000 4 30

2001 1 31

29

-31

-366

Monday

……

代码贴上:

/*    School ~  DongHua university
Turbo Test System , Test One -- Record ~
Codes	created by the rebuilt boy 	ManTruer
Student ID  :	151340112
Class  	:		Xin'an 1501
Date 	:	    2017.03.20
*/
#include <bits/stdc++.h>
using namespace std;
int op;// operation selecting flag
int daysOfMonth[] = { 0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,    31,0,31,30};// is  leap year or not , and index from 1 to 12 ,not from zero .

struct Date{
int 	day, month, year;
};
bool isLeapYear( int y){
if( !(y%400 )  ||  ( !(y%4)  &&  y%100) )
return true;
return false;
}

Date AddDay( struct Date d, int days){
d.day += days;

while(  d.day > daysOfMonth[ d.month ] ){   //over than the biggest day number .
if ( 2 == d.month){
if(  isLeapYear( d.year ) ) {
daysOfMonth[2] = 29;
if (  d.day > daysOfMonth[ d.month ] ){
d.day -= daysOfMonth[ d.month ];
d.month ++;

if( d.month >12 ){
d.month -= 12;
d.year ++;
}
daysOfMonth[2] = 0; // remember  this step .
}
}
else {
daysOfMonth[2] = 28;
if (  d.day > daysOfMonth[ d.month ] ){
d.day -= daysOfMonth[ d.month ];
d.month ++;

if( d.month >12 ){
d.month -= 12;
d.year ++;
}
daysOfMonth[2] = 0;
}
}
}
else{
d.day -=    daysOfMonth[ d.month ];
d.month ++;

if( d.month >12 ){
d.month -= 12;
d.year ++;
}
}
}
if( 29==d.day  &&  2==d.month  &&   !isLeapYear( d.year )  )  // d.year maybe had changed .
d.day = 28;   // 2016.02.29 ->2017.02.29 WRONG!!
return d;
}

Date AddMonth( struct Date d, int months){
d.month += months;
while( d.month >12 ){
d.month -= 12;
d.year ++;
}
if(  isLeapYear( d.year ))
daysOfMonth[2] = 29;
else
daysOfMonth[2] = 28;

if (   d.day > daysOfMonth[ d.month ] )
d.day = daysOfMonth[ d.month];

return d;
}

Date AddYear( struct Date d, int years){
d.year += years;
if(  isLeapYear( d.year ))
daysOfMonth[2] = 29;
else
daysOfMonth[2] =28;

if (   d.day > daysOfMonth[ d.month ] )
d.day = daysOfMonth[ d.month];

return d;
}

int Subtract( struct Date d, struct Date d0) {
int temp = 0;// for counting days

for(  int i = 1900; i<d.year; ++i)
temp += (  isLeapYear( i)? 366 : 365);

if(   isLeapYear( d.year ))
daysOfMonth[2] = 29;
else  daysOfMonth[2] = 28;
for( int i = 1;  i < d.month; ++i)   // only need to think about d.year this year .
temp +=  daysOfMonth[i] ;

daysOfMonth[2] = 0;	// do not forget this step .
temp += d.day;

// 都从公元1年1月1日起, 先加 后减 即可得到差值。但是考虑了实际测试样例为了加快运算可以从 1900甚至更大一点的数开始。。。

for(  int i = 1900; i<d0.year; ++i)
temp -= (  isLeapYear( i)? 366 : 365);

if(   isLeapYear( d0.year ))
daysOfMonth[2] = 29
4000
;
else  daysOfMonth[2] = 28;
for( int i = 1;  i < d0.month; ++i)   // only need to think about d.year this year .
temp -=  daysOfMonth[i] ;

daysOfMonth[2] = 0;	// do not forget this step .
temp -= d0.day;

return temp;
}

int   GetWeekDay (  struct  Date d){        // not Zeller ~ w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
// 基姆拉尔森计算公式 :   W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1) mod 7
if( 1 == d.month  ||  d.month == 2){
d.month += 12;
d.year --;
}//把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。
// - d.year/100 !!! “- - - ” not “  + ”.
return (  d.day + 2*d.month + 3*(d.month+1)/5 + d.year + d.year/4 - d.year/100 + d.year/400 ) % 7 ;
}

int main(){
char WeekDayNames[][15]={ "Monday", "Tuesday", "Wednesday", "Thursday","Friday", "Saturday","Sunday"};

Date d1,d2;
int n;
while( cin>>op) {
switch(op){
case 1://add days
cin>>d1.year>>d1.month>>d1.day>>n;
d2	=	AddDay( d1, n);
cout<<d2.year<<" "<<d2.month<<" "<<d2.day<<endl;
break;
case 2://add	months
cin>>d1.year>>d1.month>>d1.day>>n;
d2	=	AddMonth( d1, n);
cout<<d2.year<<" "<<d2.month<<" "<<d2.day<<endl;
break;
case 3://add years
cin>>d1.year>>d1.month>>d1.day>>n;
d2	=	AddYear( d1, n);
cout<<d2.year<<" "<<d2.month<<" "<<d2.day<<endl;
break;
case 4://subtracting
cin>>d1.year>>d1.month>>d1.day>>d2.year>>d2.month>>d2.day;
cout<<	Subtract( d1, d2)<<endl;
break;
case 5://output the weekday
cin>>d1.year>>d1.month>>d1.day;
//cout<<GetWeekDay(d1)<<endl;
cout << WeekDayNames[ GetWeekDay(d1)]<<endl;
break;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息