小小万年历
#include<stdio.h>
#include<time.h>
typedef struct tm tm;
int mon_sum_day[13]={31,28,31,30,31,30,31,31,30,31,30,31};//每个月的日期
char mon_name[13][10]={"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};
char weed_name[8][10]={"星期天","星期一","星期二","星期三","星期四","星期五","星期六"};
char year_type[3][10]={"闰年","平年"};
/* tm 型的封装struct tm {
int tm_sec; /* 秒,范围从 0 到 59
int tm_min; /* 分,范围从 0 到 59
int tm_hour; /* 小时,范围从 0 到 23
int tm_mday; /* 一月中的第几天,范围从 1 到 31
int tm_mon; /* 月份,范围从 0 到 11
int tm_year; /* 自 1900 起的年数
int tm_wday; /* 一周中的第几天,范围从 0 到 6
int tm_yday; /* 一年中的第几天,范围从 0 到 365// 主要平年355,闰年356//
int tm_isdst; /* 夏令时
};*/
tm* get_now_day()//获得今天的日期,struct tm 型
{
time_t timet;
tm *info;
time(&timet);
info = localtime(&timet);
return info;
}
void puthuanhan()//输出一行'-'
{
printf("-----------------------------------------------------------------------------------------------\n");
}
int caicaigongsi(int y,int m,int d)//蔡勒公式
{
if(m==1||m==2)
y--,m+=12;
int c=y/100;
y=y-c*100;
int week=y+y/4+c/4-2*c+26*(m+1)/10+d-1;
while(week<0)
week+=7;
week%=7;
return week;
}
void putkong(int sum,int n)//输出空格 sum次,每次n个
{
int i;
int j;
for(i=0;i<sum;i++)
{
for(j=0;j<n;j++)
{
putchar(' ');
}
}
}
int is_usually_year(int year)//平年闰年判断
{
if(year%4==0&&year%100!=0)
{
return 0;
}
else return 1;
}
int is_legalday(tm *now_day)//对于当前日期合法性判断
{
if(now_day->tm_mon>11||now_day->tm_mon<0) {printf("输入日期错误(输入月份太大或太小)\n");return 0;}
if(mon_sum_day[now_day->tm_mon]<now_day->tm_mday) {printf("输入日期错误(输入日期超过输入月份的最大日期)\n");return 0;}
return 1;
}
void p_now_mon(tm *now_day)//输出当前月份的月历
{
int t=is_usually_year(now_day->tm_year);
int i=1;
if(!is_legalday(now_day)) {return;}
if (t == 0)
{
mon_sum_day[1]++;
}
puthuanhan();
printf("%30d(%s) %s\n",now_day->tm_year+1900,year_type[t],mon_name[now_day->tm_mon]);
printf("| Sun | Mon | Tue | Wed | Thu | Fir | Sta |\n");
int mon_first_day_wday=caicaigongsi(now_day->tm_year+1900,now_day->tm_mon+1,1);
for(i=0;i<mon_first_day_wday;i++)
{
putchar('|');
putkong(1,9);
}//对于每个月1号前空出来的部分的处理
for(i=1;i<=mon_sum_day[now_day->tm_mon];i++)
{
if((mon_first_day_wday+i-1)%7==0&&i!=1) {putchar('|');putchar('\n');}
if(i!=now_day->tm_mday)
{
putchar('|');
putkong(1,2);
printf(" %2d",i);
putkong(1,4);
}//不是今天
else
{
printf("| *%2d*",i);
putkong(1,3);
}//是今天
}// 对于每一天的处理
for(;(mon_first_day_wday+i-1)%7!=0;i++)
{
putchar('|');
putkong(1,9);
}
putchar('|');
putchar('\n');//对于每一个月最后一天的处理
puthuanhan();
mon_sum_day[1]=28;//无论2月份的天数是否修改过,都改成28天
}
void p_now_day(tm* a)
{
printf("今天是%d年%d月%d日,%s,是一年中的第%d天\n",a->tm_year+1900,a->tm_mon+1,a->tm_mday,weed_name[a->tm_wday],a->tm_yday);
}
void day_perfect(tm *a)
{
a->tm_wday=caicaigongsi(a->tm_year+1900,a->tm_mon+1,a->tm_mday);
int n=0;
for(int i=0;i<a->tm_mon;i++)
{
n+=mon_sum_day[i];
}
a->tm_yday=n+a->tm_mday;
}
int main()
{
// char rabbish[100];
char in[1000];
tm *text;
while(1)
{
puthuanhan();
printf("请选择模式\n输入'm'输出当前日期的月历\n输入'n'输出当前日期\n输入'q'进行日期查询\n输入'e'结束程序\n");
puthuanhan();
scanf("%s",in);
text=get_now_day();
if(in[0]=='m')
{
p_now_mon(text);
}
else if(in[0]=='n')
{
p_now_day(text);
}
else if(in[0]=='q')
{
puthuanhan();
printf("查找模式启动,输入F6或Ctrl+Z结束\n");
while(1)
{
int k=0;
printf("请输入要查找的日期(年/月/日)\n");
if( ( k=scanf("%d/%d/%d",&text->tm_year,&text->tm_mon,&text->tm_mday) )==EOF)break;//双等式的括号很重要,不加就是给k附个bool值
if(k!=3)//k==3 说明赋值成功,否则失败
{
rewind(stdin);//从缓冲区输入进垃圾桶(这些信息都没用了),不加这个会导致非数字字符一直卡在缓冲区,进入无限循环。
printf("输入日期格式错误\n");
continue;
}
text->tm_year-=1900;text->tm_mon-=1;//在struct tm封装型内,日期是以1900年为0年,月份减一;
day_perfect(text);
p_now_mon(text);
}
printf("查找模式关闭\n");
}
else if(in[0]=='e')
{
break;
}
else
{
printf("输入错误,请重新输入\n");
}
}
}