一些日期计算
给定日期和星期几求另一个日期是星期几
容斥
#include<cstdio>
using namespace std;
int days[14]={0,31,28,31,30,31,30,31,31,30,31,30,31,0};
int dayRest[14],dayBegin[14];
struct Date{
int year,month,day;
Date(int y,int m,int d):year(y),month(m),day(d){
}
bool is29days() const{
if(year%100) return !(year%4);
return !(year%400);
}
static bool is29days(int y){
if(y%100) return !(y%4);
return !(y%400);
}
int dayOfRest() const{
if(month>2||!is29days())
return dayRest[month]-day;
return dayRest[month]-day+1;
}
int dayOfBegin() const{
if(is29days()) return 366-dayOfRest();
return 365-dayOfRest();
if(month<=2||!is29days())
return dayBegin[month-1]+day;
return dayBegin[month-1]+day+1;
}
void print(){
printf("%d-%d-%d\n",year,month,day);
}
static int dayOfYear(int year){
return year*365+year/4-year/100+year/400;
}
static int dayOfYear(int yearBegin,int yearEnd){
return dayOfYear(yearEnd)-dayOfYear(yearBegin-1);
int day=0;
for(int i=yearBegin;i<=yearEnd;++i)
if(is29days(i)) day+=366;
else day+=365;
return day;
}
friend bool operator <(const Date d1,const Date d2){
if(d1.year!=d2.year) return d1.year<d2.year;
if(d1.month!=d2.month) return d1.month<d2.month;
if(d1.day!=d2.day) return d1.day<d2.day;
}
friend bool operator >(Date d1,Date d2){
return d2<d1;
}
friend int operator -(const Date d2,const Date d1){//d2-d1
if(d1<d2){//[d1,d2]
if(d1.year==d2.year){
return d2.dayOfBegin()-d1.dayOfBegin();
}
int day=d1.dayOfRest()+d2.dayOfBegin();
day+=dayOfYear(d1.year+1,d2.year-1);
return day;
}
return -(d1-d2);
}
};
int dayofweek(Date d1,int day1,Date d2){
int day2=(day1+(d2-d1)%7+7)%7;
if(!day2) day2=7;
return day2;
}
int main(){
for(int i=1;i<=12;++i){
dayBegin[i]=dayRest[i]=days[i];
}
for(int i=2;i<=12;++i)
dayBegin[i]+=dayBegin[i-1];
for(int i=11;i>=1;--i)
dayRest[i]+=dayRest[i+1];
// printf("%d\n",dayofweek(Date(1999,12,25),6,Date(2022,2,20)));
printf("%d\n",dayofweek(Date(2021,12,25),6,Date(2022,2,28)));
return 0;
}