当我看到Linux系统有这样一个命令system(“cal”)可以打印日历后,自己就想着也做一个,于是就上网找了找万年历的相关资料:
由于万年历具有以下特点:
1 平年365天(52周+1天),闰年366天(52周+2天),平年2月28天,闰年2月29天。由于公元1月1日设为星期六,故3月1日为星期三。为使算法达到最简,故本算法以“星期”为计算单位,且选3月1日为基月。
2 每400年整一闰,或每4年且不为百年的一闰,即凡能被400整除,或不能被100整除但能被4整除的年份为闰年。
3 每 4年(3个平年+1个闰年)共208周+5天
每百年共100*(208周+5天)-1天=5217周+5天
每400年共4*(5217周+5天)+1天(整400年闰)=20871周+0天,即每400年一个轮回。
#include <stdio.h>
int total_days = 0;//全局变量
int month_days = 0;//全局变量
int week_days = 0;//全局变量
int TotalDays(int year, int month)
{
int y, mon;
for (y = 1900; y < year; y++)//计算从1900年至今的所有年份的总天数
{
if ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0))
{
total_days += 366;
}
else
{
total_days += 365;
}
}
for (mon = 1; mon < month; mon++)//加上从1月至所查询月份的总天数
{
if (mon == 2)//二月
{
if ((year % 4 == 0 && y % 100 != 0) || (year % 400 == 0))//闰年29天
{
total_days += 29;
}
else
{
total_days += 28;
}
}
else if (mon == 4 || mon == 6 || mon == 9 || mon == 11)//每月有30天的月份
{
total_days += 30;
}
else//每月有31天的月份
{
total_days += 31;
}
}
}
int WeekDay()//判断所查询月份的第一天是星期几
{
total_days += 1;
week_days = total_days % 7;
}
int MonthDays(int year, int month)//判断当月共有多少天
{
if (month == 2)
{
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{
month_days = 29;
}
else
{
month_days = 28;
}
}
else if (month == 4 || month == 6 || month == 9 || month == 11)
{
month_days = 30;
}
else
{
month_days = 31;
}
}
void print()//打印信息
{
int i;
printf("日 一 二 三 四 五 六\n");
for(i = 1; i <= week_days; i++)
{
printf(" ");
}
int k;
for(k = 1; k <= month_days; k++)
{
if(total_days % 7 == 6)
{
printf("%2d\n", k);
}
else
{
printf("%2d ", k);
}
total_days++;
}
printf("\n\n");
}
int main()
{
int year=0, month=0;
system("clear");
printf("请输入查询时间: 年 月\n");
system("tput cup 0 16");
scanf("%d", &year);
system("tput cup 0 24");
scanf("%d", &month);
printf("\n");
TotalDays(year, month);
WeekDay(year, month);
MonthDays(year, month);
print();
return 0;
}