新手上路,这是基于公历第一年的第一天是星期一的原理而做出的简易万年历,总共只有四个函数便可实现计算,应该说还是一个比较简洁的也比较简单的万年历,欢迎大家为它的进一步完善和改进提出建议
#include<stdio.h>
#include <time.h>
#define YEARDAYS 365 //定义一年天数
#define YEARMONS 12 //定义一年月数
#define WEEKDAYS 7 //定义一周天数
//用枚举数据结构定义一个星期里的每一天的称呼
typedef enum{
Sun,Mon,Tue,Wed,Thu,Fri,Sat
}WEEK;
//用枚举数据结构定义十二个月
typedef enum{
JAN=1,FEB,MAT,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC
}MONTH;
//输出万年历
void printMonth(const WEEK firstDay, int length)
{
WEEK weekDay = firstDay ;
int i;
printf(" Sun Mon Jue Wed Thu Fri Sat\n");
for(i=1;i<=weekDay;i++)
{
printf(" ");//输入空位以顶替当月第一周第一天之前的所缺天数
}
for(i=1;i<=length;++i)
{
weekDay = (++weekDay) % WEEKDAYS;
printf("%7d",i);
if(weekDay == 0)
printf("\n");
}
printf("\n");
}
//判断是否是闰年,是就返回1,不是就返回0
int isLeapYear(const int y)
{
return(y % ( y % 100 ? 4 : 400 ) ? 0 : 1);
}
//得到当年的第一个月的第一天是第一周的第几天
int getYearOfDay(const int year)//得到年份
{
int yearNumber = year - 1;//由于公元纪年的起点是公元1年
int n = 0,i=0;
if(year == 0)
return 1;
for( i=1;i<year;i++)
if(isLeapYear(i)==1)
n++;//记录出因为闰年而多出的天数
return(YEARDAYS * yearNumber + n+1) % WEEKDAYS;//1是第一天
}
//计算天数
void printCalendar(const int y , const int m)
{
int i=0;
WEEK yDAY = getYearOfDay(y);
int vDay = isLeapYear(y);//如果是闰年则等于1
int monWeeks [YEARMONS+1];
int monLen [YEARMONS+1];
//为每个月设置具体天数
monLen[0] = 0;
monLen[JAN] = 31;
monLen[FEB] = 28 + vDay;//计算闰月
monLen[MAT] = 31;
monLen[APR] = 30;
monLen[MAY] = 31;
monLen[JUN] = 30;
monLen[JUL] = 31;
monLen[AUG] = 31;
monLen[SEP] = 30;
monLen[OCT] = 31;
monLen[NOV] = 30;
monLen[DEC] = 31;
monWeeks[0] = 0;
monWeeks[JAN] = yDAY;//得到当年的第一个月的第一天是第一周的第几天
for(i = JAN ; i < DEC ; i++)
monWeeks[i+1] = ((monWeeks[i] + monLen[i]) % WEEKDAYS);//得到每个月的第一天是第一周的第几天
printf("&d, &d \n", y, m);
printf("---------------------------------------------------\n");
printMonth(monWeeks[m] , monLen[m]);//传入当月的第一天是第一周的第几天,和当月的天数
printf("\n");
}
int main(void)
{
struct tm when; //定义系统自带的tm结构体对象when
time_t now;
int Y = 0;//所需的年份储存变量
int m = JAN;//所需的月份储存变量
int quit = 0;//循环控制变量
//设置循环,便于多次查询
time( &now );//获取当前时间,存now里
when = *localtime( &now ); //获取当地时间,根据地址传值;
printf( "Current time is %s\n", asctime( &when ) );//输出当前时间
printCalendar (when.tm_year+1900,when.tm_mon+1);//输出当前万年历
while(!quit)
{
printf("Please input the year,month;-1 for break\n");//提示输入所需年月
scanf("%d,%d",&Y,&m);//输入年月
if(Y == -1)
quit = 1;//退出程序
else if(Y < 10000 && Y > 0 && m > 0 && m < 13)
printCalendar (Y,m);//输出Y年m当月的万年历
else
printf("请按要求输入数字!\n");//确保输入正确
}
return 0;
}