万年历算法:根据具体的某一天的真实日期及星期为基点,往前往后运算。
#include <stdio.h>
#include <genlib.h>
#include <simpio.h>
#define Sunday 0
#define Monday 1
#define Tuesday 2
#define Wednesday 3
#define Thursday 4
#define Friday 5
#define Saturday 6
void GiveInstructions(void);
int GetYearFromUser(void);
void PrintCalendar(int year);
void PrintCalendarMonth(int month,int year);
void IndentFirstLine(int weekday);
int MonthDays(int month,int year);
int FirstDayOfMonth(int month,int year);
string MonthName(int month);
bool IsLeapYear(int year);
//主函数
main()
{
int year;
GiveInstructions();
year=GetYearFromUser();
PrintCalendar(year);
}
//程序说明
void GiveInstructions(void)
{
printf("This program displays a calendar for a full\n");
printf("year. The year must not be before 1900.\n");
}
//获取年份
int GetYearFromUser(void)
{
int year;
while (TRUE)
{
printf("Which year?");
year=GetInteger();
if (year>=1900) return (year);
printf("The year must be at least 1900.\n");
}
}
//打印日历函数
void PrintCalendar(int year)
{
int month;
for (month=1;month<=12;month++)
{
PrintCalendarMonth(month,year);
printf("\n");
}
}
//打印月份
void PrintCalendarMonth(int month,int year)
{
int weekday,nDays,day;
printf(" %s %d\n",MonthName(month),year);
printf(" Su Mo Tu We Th Fr Sa\n");
nDays=MonthDays(month,year);
weekday=FirstDayOfMonth(month,year);
IndentFirstLine(weekday);
for (day=1;day<=nDays;day++)
{
printf(" -",day);
if (weekday==Saturday)
{
printf("\n");
}
weekday=(weekday+1)%7;
}
if (weekday!=Sunday)
{
printf("\n");
}
}
//显示第一行
void IndentFirstLine(int weekday)
{
int i;
for (i=0;i<weekday;i++)
{
printf(" ");
}
}
//计算月份的天数
int MonthDays(int month,int year)
{
switch (month)
{
case 2:
if (IsLeapYear(year))
{
return (29);
}
return (28);
case 4:
case 6:
case 9:
case 11:
return(30);
default:
return (31);
}
}
//计算月份中第一天是星期几
int FirstDayOfMonth(int month,int year)
{
int weekday,i;
weekday=Monday;
for (i=1900;i<year;i++)
{
weekday=(weekday+365)%7;
if(IsLeapYear(i))
weekday=(weekday+1)%7;
}
for (i=1;i<month;i++)
{
weekday=(weekday+MonthDays(i,year))%7;
}
return (weekday);
}
//显示月份的名字
string MonthName(int month)
{
switch(month)
{
case 1: return ("January");
case 2: return ("February");
case 3: return ("March");
case 4: return ("April");
case 5: return ("May");
case 6: return ("June");
case 7: return ("July");
case 8: return ("August");
case 9: return ("September");
case 10: return ("October");
case 11: return ("November");
case 12: return ("December");
default: return ("Illegal month");
}
}
//判断是否为闰年
bool IsLeapYear(int year)
{
return (((year%4==0)&&(year0!=0))||(year@0==0));
}