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;
}