思路:
以2000年1月1号为例。知道2000.1.1是星期六,通过知道1月有多少天就知道2000.2.1号是星期几,依次就可得到2000.12.1是星期几,从而就会得到2001年的1月1号是星期几,这样就可得到输入年的指定月份1号是星期几。当知道给定年得月份知道了1号的具体星际几,然后就可以打印出这个月的所有日期。
#include<stdio.h> #include<stdlib.h> int months[2][13]={ //每个月的天数,2月分为28天和29天分两种情况 {0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31} }; int is_leap_year(int year) //判断是否为闰年 { return (year%4==0)&&(year%100!=0)||(year%400==0); } int frist_day_year(int year) //求当前年的1月1号星期几 { int bs_year=2000; //以2000年为例 int bs_day=6; //1月1号星期六 int total=0; //天数 int i=0; for(i=bs_year;i<year;i++) //2000年到当前年的所有天数加起来 { total+=365+is_leap_year(i); //是闰年is_leap_year(i)为1 } total+=bs_day; //将前面的6要加起来 return total % 7; //当前年1月1号是星期几 } int frist_day_month(int year,int month,int frist) //求当前月1月1号是星期几 { int total=frist; int i=0; for(i=1;i<month;i++) //将当前月之前的所有天数 { total+=months[is_leap_year(year)][i]; } return total % 7; //返回当前月1月1号星期几 } void show(int year,int month,int frist) { printf("Sun Mon Tue Wed The Fri Sat\n"); //打印星期标识 int i=0; for(i;i<frist;i++) //将frist当前1月1号之前的补上空格 printf(" "); //一次补四个,因为打印星期标识时中间隔4个字符 for(i=1;i<=months[is_leap_year(year)][month];i++) { printf("%3d ",i); //三位显示数据,一位显示空格 if((i+frist)%7==0) //换行 printf("\n"); } } int main(){ int year; int month; printf("year/month"); scanf("%d%d",&year,&month); int frist=frist_day_year(year); //当前年的1月1号 printf("2018年1月1日星期为:%d\n",frist); frist=frist_day_month(year,month,frist); // 当前月的1号 printf("当前月1号的星期为: %d\n",frist); show(year,month,frist); //显示 printf("\n"); }
输入2018年2月,运行结果为:
2018年1月1日星期为:1 当前月1号的星期为: 4 Sun Mon Tue Wed The Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28