曾听人说相隔六十年的挂历就可以重复来使用,的确就年份而言六十年是一个甲子的轮回,但星期值是否也能完全吻合呢?
这就引出一个关于星期值的推算问题,我们知道每个平年有365天,且每4年会有一个闰年,这样在60年中,共有60/4=15个闰年,共有21915天(60*365+15),以21915%7=5,故星期值会偏移5天,所以星期值是不能完全重合的,也就无法如此来使用。
那如何来按公历时间进行星期值的推算呢?
这就需要有个基准点,以1984年1月1日为例,是星期日且该年为闰年。
设X=1985年1月1日(异年同日推算),则推算方法为: 日期差d=(1985-1984)*365+1=366,d%7=2+星期日=星期二。 在通常情况下,每年52周,52x7=364,则在平年的情况下,每过一年,则相应日期的星期值会向后推一天。若逢闰年则星期值需向后推二天,以补偿闰年所多出的一天。 设X=1985年1月10日(同年异日推算),则推算方法为: 日期差d=年差(1985-1984)*365+1+日差(10-1)=366+9=375,d%7=4+星期日=星期四。 设X=1985年3月12日(异年异日推算),则推算方法为: 首先进行异年同日推算,再进行同年异日推算,则有: 日期差d=年差(1985-1984)*365+1+日差(12-1)+月差(31+28)=366+11+59=436,d%7=2+星期日=星期二。 故通用的推算方法为: 日期差d=年差((x-1984)*365+(x-1984)/ 4+1 )+月差(月份积日)+日差(日期-1)-闰月前部修正(<2月) 星期值=d%7+星期日。 注:若使推算的范围更广,则可将推算的基点前移即可。 月份: 1 2 3 4 5 6 7 8 9 10 11 12 积日: 0 31 59 90 120 151 181 211 242 272 303 333 设X=1988年3月12日 日期差d=4*365+2+11+59=1460+2+70=1532,d%7=6+星期日=星期六。 设X=1988年2月12日 日期差d=4*365+2+11+31=1460+2+42=1504-1=1503,d%7=5+星期日=星期五。 星期值推算的程序为: printf("星期值推算: \r\n");
printf("1985.1.1\r\n");
//1984.1.1=星期日 闰年 i=1985->2017
for(i=1985;i<2017;i++)
{
printf("%d年 \r\n",i);
t=(i-1984);
for(j=1;j<13;j++)
{
for(b=1;b<29;b++)
{
printf("%d月 \r\n",j);
printf("%d日\r\n",b);
p=b-1;
if(j==1) k=p;
if(j==2) k=31+p;
if(j==3) k=59+p;
if(j==4) k=90+p;
if(j==5) k=120+p;
if(j==6) k=151+p;
if(j==7) k=181+p;
if(j==8) k=212+p;
if(j==9) k=243+p;
if(j==10) k=273+p;
if(j==11) k=304+p;
if(j==12) k=334+p;
if((j<3)&&(t%4==0)) k=k-1;
d=(t*365+1+k+t/4)%7;
printf("星期");
if(d==0) printf("日");
if(d==1) printf("一");
if(d==2) printf("二");
if(d==3) printf("三");
if(d==4) printf("四");
if(d==5) printf("五");
if(d==6) printf("六");
printf("\r\n");
}
}
}
推算结果验证: 电脑的显示内容
推算的结果
|