首先说一个常识:公元元年指的是0001年,0001年01月01日是周一,可以用这个作为一个基准点,下列代码是用的2022年1月1日作的基准点:
#include<stdio.h>
int main()
{
int x=0,week=0,year=0,month=0,day=0,february=0,D_value=0;
long y;
printf("请输入所需查询的日期:(格式:xxxx xx xx):");
scanf("%d%d%d",&year,&month,&day);
if(year%4==0&&year%100!=0)
february=29;
else if(year%400==0)
february=29;
else
february=28;
if(month==2&&day>february)
printf("输入格式错误!!");
else if(year<2022)
{
switch(month)
{
case 1 :D_value=31+30+31+30+31+31+30+31+30+31+february+31-day;break;
case 2 :D_value=31+30+31+30+31+31+30+31+30+31+february-day;break;
case 3 :D_value=31+30+31+30+31+31+30+31+30+31-day;break;
case 4 :D_value=31+30+31+30+31+31+30+31+30-day;break;
case 5 :D_value=31+30+31+30+31+31+30+31-day;break;
case 6 :D_value=31+30+31+30+31+31+30-day;break;
case 7 :D_value=31+30+31+30+31+31-day;break;
case 8 :D_value=31+30+31+30+31-day;break;
case 9 :D_value=31+30+31+30-day;break;
case 10:D_value=31+30+31-day;break;
case 11:D_value=31+30-day;break;
case 12:D_value=31-day;break;
}
for(x=2022;x>year;x--)
{
{
if(x%4==0&&x%100!=0)
y=366;
else if(x%400==0)
y=366;
else
y=365;
}
D_value+=y;
}
week=D_value%7;
switch(week)
{
case 1:printf("%04d年%02d月%02d日是星期五",year,month,day);break;
case 2:printf("%04d年%02d月%02d日是星期四",year,month,day);break;
case 3:printf("%04d年%02d月%02d日是星期三",year,month,day);break;
case 4:printf("%04d年%02d月%02d日是星期二",year,month,day);break;
case 5:printf("%04d年%02d月%02d日是星期一",year,month,day);break;
case 6:printf("%04d年%02d月%02d日是星期日",year,month,day);break;
case 0:printf("%04d年%02d月%02d日是星期六",year,month,day);break;
}
}
else
{
switch(month)
{
case 1 :D_value=day;break;
case 2 :D_value=day+31;break;
case 3 :D_value=day+31+february;break;
case 4 :D_value=day+31+february+31;break;
case 5 :D_value=day+31+february+31+30;break;
case 6 :D_value=day+31+february+31+30+31;break;
case 7 :D_value=day+31+february+31+30+31+30;break;
case 8 :D_value=day+31+february+31+30+31+30+31;break;
case 9 :D_value=day+31+february+31+30+31+30+31+31;break;
case 10:D_value=day+31+february+31+30+31+30+31+31+30;break;
case 11:D_value=day+31+february+31+30+31+30+31+31+30+31;break;
case 12:D_value=day+31+february+31+30+31+30+31+31+30+31+30;break;
}
for(x=2022;x<year;x++)
{
{
if(x%4==0&&x%100!=0)
y=366;
else if(x%400==0)
y=366;
else
y=365;
}
D_value+=y;
}
week=D_value%7;
switch(week)
{
case 1:printf("%04d年%02d月%02d日是星期六",year,month,day);break;
case 2:printf("%04d年%02d月%02d日是星期日",year,month,day);break;
case 3:printf("%04d年%02d月%02d日是星期一",year,month,day);break;
case 4:printf("%04d年%02d月%02d日是星期二",year,month,day);break;
case 5:printf("%04d年%02d月%02d日是星期三",year,month,day);break;
case 6:printf("%04d年%02d月%02d日是星期四",year,month,day);break;
case 0:printf("%04d年%02d月%02d日是星期五",year,month,day);break;
}
}
return 0;
}
说一下这个程序的思路:通过一个基准点,算出输入日期距离该基准点的天数,再用天数除以7取余,便能推断出输入日期在星期几。(D_value为输入年份到基准点的差值,week为差值除以7取余的结果,由此取余结果判断星期)
我们都知道二月在闰年有29天,平年里28天,人总不能一直替它输入下去,所以得让程序自动化,因此就需要用到一个判断语句让其自动赋值。定义变量february就是二月的天数,用if函数判断当年是否为闰年,给february赋上正确的天数。
再根据输入的年份判断该年份是否在基准点之前,若在基准点之前,那么日期就该用:当前月份之后的所有月份总天数+(当前月份的所有天数-输入的日期数)。为了方便理解,解释一下:如上程序,2022年1月1日为基准点,输入2021 01 07,要得输入与基准点的日期差距,就得把二到十二月的所有天数全部加上,而此时还没算上1月的天数,因为当前是7号,所以得用一月的总天数31去减7,因为年份在基准点之前,所以需要倒过来求天数。若在基准点之后,那就按顺序求便可,求基准点之后的应该很容易理解,就不做过多解释了。
求到了这个年份里的天数,那么剩下的就是距离基准点整年的天数了。我们知道平年有365天,闰年366天,所以用一个判断语句给整年差值y赋值366或365便可,闰年的条件是:被4整除且不被100整除,但是这只是1普通闰年,我们还需要将世纪闰年也判断进去,世纪闰年是能被400整除的年份。那为什么要加上世纪闰年呢?可以说这算是弥补用普通闰年判断带来的误差。例如:2000年是世纪闰年,有366天,但是不加上世纪闰年的判断,那程序就会断定2000年为平年,再往前的日期就会出现差值造成误差。
那么,接下来的问题转到求整年日期上。这里选用的循环函数嵌套if函数,为什么这么选择?上边说了,要用if来判断递加或者递减的日期里有哪些为平年哪些是闰年,以准确赋值。
接下来就比较简单了,用差值D_value除以7取余,将结果赋值给week,用switch选择函数便能求出来了。