日期问题

int md[]={0,0,31,28,31,30,31,30,31,31,30,31,30};
int days[12]={31,28,31,30,31,30,31,31,30,31,30,31};
struct date{
    int year,month,day;
};

(1)合法性判断

inline int legal(date a){
    if (a.month<0||a.month>12)
         return 0;
    if (a.month==2)
         return a.day>0&&a.day<=28+leap(a.year);
    return a.day>0&&a.day<=days[a.month-1];
}

(2)比较日期大小

inline int datecmp(date a,date b){
   if (a.year!=b.year)
	   return a.year-b.year;
   if (a.month!=b.month)
	   return a.month-b.month;
   return a.day-b.day;
}

(3)闰年判断

inline int leap(int year){
    return (year%4==0&&year%100!=0)||year%400==0;
}

(4)日期序列化(日期转天数偏移)

问题:计算指定日期是第几天

//days(0,1,1)==1
inline int days(int y, int m, int d){
    d+=m<=2 && isly(y) ? md[m]-1 : md[m];
    d+=365*y+y/4-y/100+y/400+1;
    return d;
}
//or
int date2int(date a){
    int ret=a.year*365+(a.year-1)/4-(a.year-1)/100+(a.year-1)/400,i;
    days[1]+=leap(a.year);
    for (i=0;i<a.month-1;ret+=days[i++]);
   	days[1]=28;
   	return ret+a.day;
}

(5)天数偏移转日期

date int2date(int a){
    date ret;
    ret.year=a/146097*400;
    for (a%=146097;a>=365+leap(ret.year);a-=365+leap(ret.year),ret.year++);
        days[1]+=leap(ret.year);
    for (ret.month=1;a>=days[ret.month-1];a-=days[ret.month-1],ret.month++);
        days[1]=28;
    ret.day=a+1;
    return ret;
}

(6)星期判断

问题:计算指定日期是星期几

//0-日,1-一,2-二,3-三,4-四,5-五,6-六
inline int day(int y, int m, int d){
    return (days(y,m,d)+5)%7;
}
//or
int weekday(date a){
    int tm=a.month>=3?(a.month-2):(a.month+10);
    int ty=a.month>=3?a.year:(a.year-1);
    return (ty+ty/4-ty/100+ty/400+(int)(2.6*tm-0.2)+a.day)%7;
}
  • 测试

#include<cassert>
#include<iostream>
using namespace std;
void test(){
 assert(days(0,1,1)==1);
 assert(days(0,1,31)==31);
 assert(days(0,2,1)==32);
 assert(days(0,3,1)-days(0,2,28)==2);
 assert(days(0,12,31)-days(0,1,1)==365);
 assert(days(1,1,1)-days(0,12,31)==1);
 assert(days(1,3,1)-days(1,2,28)==1);
 assert(days(1,12,31)-days(0,12,31)==365);
 assert(days(4,12,31)-days(3,12,31)==366);
 assert(days(100,3,1)-days(100,2,28)==1);
 assert(days(101,1,1)-days(100,1,1)==365);
 assert(days(401,2,28)-days(400,2,28)==366);
 assert(days(1000,3,1)-days(1000,2,28)==1);
 assert(days(2000,3,1)-days(2000,2,28)==2);
 assert(days(2000,2,1)-days(2000,1,30)==2);
 assert(days(2100,3,1)-days(2100,2,28)==1);
 assert(days(2000,4,1)-days(2000,3,30)==2);
 assert(days(2000,5,1)-days(2000,4,30)==1);
 assert(days(2000,6,1)-days(2000,5,30)==2);
 assert(days(2000,7,1)-days(2000,6,30)==1);
 assert(days(2000,8,1)-days(2000,7,30)==2);
 assert(days(2000,9,1)-days(2000,8,30)==2);
 assert(days(2000,10,1)-days(2000,9,30)==1);
 assert(days(2000,11,1)-days(2000,10,30)==2);
 assert(days(2000,12,1)-days(2000,11,30)==1);
 assert(days(2001,1,1)-days(2000,12,30)==2);
 assert(days(3000,12,31)==1096093);
 assert(day(2006,6,14)==3);
 assert(day(2008,3,1)==6);
 assert(day(1985,10,3)==4);
 assert(day(2006,1,1)==0);//Sunday.
 cout<<"Accepted!"<<endl;
}
int main(){
 for(int i=2;i<=12;i++){
  md[i]+=md[i-1];
 }
 //Test
 int y1,m1,d1,y2,m2,d2;
 freopen("in.txt","r",stdin);
 while(cin>>y1>>m1>>d1)
  cout<<days(y1,m1,d1)<<endl;
 while(cin>>y1>>m1>>d1>>y2>>m2>>d2)
  cout<<days(y2,m2,d2)-days(y1,m1,d1)<<endl;
 //More Test
 test();
 return 0;
}

猜你喜欢

转载自blog.csdn.net/u013228808/article/details/83061616