#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#define UP 0x48
#define DOWN 0x50
#define LEFT 0x4b
#define RIGHT 0X4d
#define PAGEUP 0x49
#define PAGEDOWN 0x51
struct Date
{ int year;
int month;
int day;
};
struct Date systemDate,currentDate;
int iday[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
char cday[13][7]={"\0","一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};
int GetWeekday(int year,int month,int day);
int LeapYear(int year);
void CheckDate();
void GetKey();
void PrintSpace(int n);
void PrintWeek(struct Date *p);
void PrintCalendar(int year,int month,int day);
void PrintYear(int year,int month,int day);
int GetWeekday(int year,int month,int day)
{ int weekday=0,sum=0,i;
if (LeapYear(year)) iday[2]=29;
else iday[2]=28;
for (i=0;i<month;i++)
sum+=iday[i];
sum+=day;
weekday=(year-1)*365+(year-1)/4-(year-1)/100+(year-1)/400+sum;
weekday%=7;
return weekday;
}
int LeapYear(int year)
{ if (year%4==0&&year%100!=0||year%400==0)
return 1;
else return 0;
}
void CheckDate()
{
}
void GetKey()
{ int init=1;
char cKey='\0',c='\0';
while(1)
{ PrintCalendar(currentDate.year,currentDate.month,currentDate.day);
if (init==1)
{ printf("\n\n\t键盘操作说明\n");
printf(" *************************\n");
printf(" 按W或w显示全年日历\n");
printf(" 按I或i查询指定日期的日历\n");
printf(" 按R或r重置为系统日期\n");
printf(" 按Q或q退出程序\n");
printf(" --------------------------\n");
printf(" 按PageUp或PageDown修改年\n");
printf(" 按上下箭头修改月\n");
printf(" 按左右箭头修改日\n");
init=0;
}
cKey= getch();
if (cKey==-32)
{cKey= getch();
switch(cKey)
{ case UP:
if(currentDate.month<12)currentDate.month++;
else {currentDate.year++;currentDate.month=1;}
break;
case DOWN:
if(currentDate.month>1)currentDate.month--;
else {currentDate.year--;currentDate.month=12;}
break;
case LEFT:
if(currentDate.day>1)currentDate.day--;
else if(currentDate.month==1){currentDate.year--;currentDate.month=12;currentDate.day=31;}
else {currentDate.month--;currentDate.day=31;}
break;
case RIGHT:
if(currentDate.day<iday[currentDate.month])currentDate.day++;
else if(currentDate.month==12){currentDate.year++;currentDate.month=1;currentDate.day=1;}
else {currentDate.month++;currentDate.day=1;}
break;
case PAGEUP:currentDate.year++;break;
case PAGEDOWN:currentDate.year--;break;
}
}
else
{
if (cKey=='I'||cKey=='i')
{ printf("\n\n输入要查询的日期(yyyy-mm-dd):");
scanf("%d-%d-%d",¤tDate.year,¤tDate.month,¤tDate.day);
CheckDate();
getchar();
}
if (cKey=='R'||cKey=='r') currentDate=systemDate;
if (cKey=='Q'||cKey=='q')
{printf("\n 确定退出(Y/N)?");
c=getchar();
if(c=='Y'||c=='y') printf("\n Bye-Bye!");return;
}
if (cKey=='W'||cKey=='w')
{system("cls");
PrintYear(currentDate.year,currentDate.month,currentDate.day);
}
}
}
}
void PrintSpace(int n) //补充占位符
{ int i;
for (i=1;i<=n;i++)
printf("%4c", '*');
}
void PrintWeek(struct Date *p) //显示星期几
{ int day;
if (p==NULL) return;
day=GetWeekday(p->year,p->month,p->day);
printf("\n ==========================");
printf("\n %4d-%02d-%02d是",p->year,p->month,p->day);
switch(day)
{ case 0:printf("星期日");break;
case 1:printf("星期一");break;
case 2:printf("星期二");break;
case 3:printf("星期三");break;
case 4:printf("星期四");break;
case 5:printf("星期五");break;
case 6:printf("星期六");break;
}
}
void PrintCalendar(int year,int month,int day)
{ int OutputDay=1;
int error=0;
int dayinLastmonth=0;
int weekday=0;
int temp=0;
if (LeapYear(year)) iday[2]=29;
else iday[2]=28;
if (day>iday[month])
{ printf("%s最多还有%d天",cday[month],iday[month]);
error=1;
}
if (day<=0)
{ printf("日期必须是正数");
error=1;
}
if (error) //日期无效,重置为系统日期
{printf("按任意键继续..... ");
getch();
year=systemDate.year;
month=systemDate.month;
day=systemDate.day;
currentDate=systemDate;
if (LeapYear(year)) iday[2]=29;
else iday[2]=28;
}
weekday=dayinLastmonth=GetWeekday(year,month,1);
//system("cls");
printf("\t%d年%d月日历",year,month);
if (LeapYear(year)) printf(" [闰年]\n\n");
else printf(" [非闰年]\n\n");
printf(" 日 一 二 三 四 五 六\n");
PrintSpace(dayinLastmonth);
while(OutputDay<=iday[month])
{printf("%4d",OutputDay);
if (weekday==6) printf("\n");
weekday=weekday>5?0:weekday+1;
OutputDay++;
}
PrintWeek(¤tDate);
}
void PrintYear(int year,int month,int day)
{ int OutputDay=1;
int OutputMonth=1;
int error=0;
int dayinLastmonth=0;
int weekday=0;
int temp=0;
if (LeapYear(year)) iday[2]=29;
else iday[2]=28;
if (day>iday[month])
{ printf("\n %s最多还有%d天",cday[month],iday[month]);
error=1;
}
if (day<=0)
{ printf("\n 日期必须是正数");
error=1;
}
if (error)
{printf("\n 按任意键继续..... ");
getch();
year=systemDate.year;
month=systemDate.month;
day=systemDate.day;
currentDate=systemDate;
}
weekday=dayinLastmonth=GetWeekday(year,1,1);
printf(" %d年全年日历",year);
if (LeapYear(year)) printf(" [闰年]\n");
else printf(" [非闰年]\n");
while(OutputMonth<=12)
{ OutputDay=1;
printf("\n\t%d年%d月\n",year,OutputMonth);
printf(" 日 一 二 三 四 五 六\n");
PrintSpace(dayinLastmonth);
while(OutputDay<=iday[OutputMonth])
{ printf("%4d",OutputDay);
if (weekday==6) printf("\n");
weekday=weekday>5?0:weekday+1;
OutputDay++;
}
printf("\n --------------------------\n");
OutputMonth++;
dayinLastmonth=weekday;
}
printf("\n 按任意键返回主界面!\n");
getch();
}
int main()
{ time_t t; //time_t为time.h定义的结构体,一般为长整型
struct tm *p; //struct tm *localtime (const time_t *__timer);
time(&t);//获取Unix时间戳,time函数返回从1970年1月1日开始所经过的秒数
p=localtime(&t);//转为时间结构
systemDate.year=p->tm_year+1900; /*获取当前年份,从1900开始,所以要加1900*/
systemDate.month=p->tm_mon+1; /*获取当前月份,范围是0-11,所以要加1*/
systemDate.day=p->tm_mday; /*获取当前月份日数,范围是1-31*/
currentDate=systemDate;
printf("\t202103C语言课程设计\n");
printf("\t设计者:智能207 XXXXXX\n\n");
system("color F4");
GetKey();
PrintWeek(¤tDate);
return 0;
}