功能:

1.该程序可以输出某年的全部月份,也可以输出某月的全天日历。

2.输入年月日输出距今天还有多少天,星期几,是否是公历节日。

注:分代码应以.h的形式分开才保证正常运行。

程序设计思路:

总天数的算法:首先用if语句判断定义年到输入年之间每一年是否为闰年,若是,该年的总天数为366则2月输出为29天,若不是,为365天,2月输出为28天。再判断系统当前月份是大月还是小月,若为大月,则输出31天;若为小月,则输出30天。利用一个函数计算出每月的第几天是星期几。根据所判断的大月、小月,通过控制符setw控制输出流格式(设置字段宽度),把该日期以前的位置用空格补上,并从该日起依次输出天数直到月底,该月中的天数加上该月一日为星期几的数字再除以7得0换行,即可完整的输出该月的日历。获取系统时间,计算当天农历日期并显示。在C++中,考虑到C语言到C++语言过渡的连续性,对结构体进行了扩展,C++的结构体可以包含函数。C++中一般使用cocout和cin时的默认格式。C++提供了在输入输出流中使用的控制符。需要注意的是:如果使用了控制符,在程序单的开头要加iostream头文件。

功能需求分析:

(1)能够显示该年的日历。假定输入的年份在1940-2040之间

(2)能够显示某月的日历。

(3)能够显示距今天还有多少天,星期几,是否是公历节日。

设计程序运行界面,具有显示各种功能的面板模块,并对各功能按钮就行时间监听;程序需要能够显示1940年到2040年的日历。要求系统能够从界面上的操作获取公历日期,计算其所对应的星期和相应的节点并显示到界面上;程序要求显示输入某年某月日历,包括公历、时间所对应的星期。要求可以自己设置一个时间点,在这一时间点做出相应的响应。对时间的更新,日历显示要求关联系统时间,能在进入程序时显示与系统时间对应的日历;程序界面的美观设计和人性化结构,要求具有良好的人机交互,容易理解界面内容,易操作;就现在的水平来说,功能1、2是可以实现,功能3有待研究,可能遇到的问题是按钮对时间的监听处理可能难度较大,还有就是在农历转公历中可能比较难获取相应的公历变化日期。

各模板函数说明:

1.0菜单显示模块程序:

void menu(){system("cls");//clears 作用是让屏幕清干净printf(" -----------------------------------\n");printf(" |---------------------------------|\n");printf(" |----------欢迎来到万年历---------|\n");printf(" |---------------------------------|\n");printf(" |----------1.查看某年日历---------|\n");printf(" | |||\n");printf(" |----------2.查看某月日历---------|\n");printf(" | |||\n");printf(" |----------3.查看某天日历---------|\n");printf(" | |||\n");printf(" |----------4.退出---------|\n");printf(" |---------------------------------|\n");printf(" -----------------------------------\n");printf("请输入你的选择:");int m;scanf_s("%d", &m);while (!(m >= 1 && m <= 4)){printf("请重新输入正确的数字:");scanf_s("%d", &m);}int z;switch (m){case 1: years();menu();break;case 2: mouth(); menu();break;case 3: day(); menu();break;case 4:system("cls");//clears 作用是让屏幕清干净printf("-----------------\n");printf("|是否确认退出???|\n");printf("-----------------\n");printf("\n");printf("---------------------------------------\n");printf("|*1确认退出*其余数字取消退出!|\n");printf("---------------------------------------\n");scanf_s("%d", &z);if (z == 1)exit(0);elsemenu();}}

1.1查询某年日历:

#pragma once#pragma onceint Month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//内部逻辑的实现//判断是否是闰年int isleapyear(int year);//判断给定年份的第一天的距1940年1月1日的总天数int sumofday(int year, int month);//设置日历外观样式//打印日历上边框voidprintBorder_up(int year);//打印日历下边框void printBorder_down(int year);//打印日历内容,分为六块,每块又由表头、衔接、表尾组成void printBody(int year);//打印日历表头void printTitle(int month1, int month2);//打印日历内容void printDate(int month1, int month2, int year);//衔接部分void part(int year, int month, int* day);int years(){system("cls");//clears 作用是让屏幕清干净printf("|----------------------------------------------|\n");printf("|----------当前功能为查看某年日历--------------|\n");printf("|----------------------------------------------|\n");printf(" 请你输入一个你想知道的年份 xxxx:");int year;scanf_s("%d", &year);while (year 2040){printf("请输入年份[1940--2040]:");scanf_s("%d", &year);}printBorder_up(year);printBody(year);printBorder_down(year);printf("\n");printf("\n");printf("|----------------------------------------------|\n");printf("|--------------按任意键回到主菜单--------------|\n");printf("|----------------------------------------------|\n");system("pause");return 0;}//判断闰年int isleapyear(int year) {if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0) {return 1;}else {return 0;}}//判断给定年份的第一天的距1940年1月1日的总天数//用以判断指定年份对应的每月的第一天是星期几int sumofday(int year, int month) {int sum = 0;int i = 1940;for (i = 1940; i < year; i++){if (isleapyear(i)) {sum += 366;}else {sum += 365;}}if (isleapyear(i)) {Month[2] = 29;}for (int i = 0; i < month; i++) {sum += Month[i];}return sum;}//打印日历上边框void printBorder_up(int year) {printf("|=====================The Calendar of Year %d====================|\n", year);}//打印日历下边框void printBorder_down(int year) {printf("|==================================================================|\n");}//打印日历内容,分为六块表,每块表又由表头、表内容组成void printBody(int year) {for (int i = 0; i < 6; i++) {//打印表头printTitle(i + 1, i + 7);//打印表内容printDate(i + 1, i + 7, year);}}//表头,两列组成void printTitle(int month1, int month2) {printf(": %2dSUN MON TUE WED THU FRI SAT%2dSUN MON TUE WED THU FRI SAT :\n", month1, month2);}//表内容的排版,part函数显示日期,分为五个部分;边框-日期-边框-日期-边框void printDate(int month1, int month2, int year) {//每次循环调用不同的函数,需要记录天数,传地址,防止丢失int day1 = 1, day2 = 1;//打印天数,最多6行,31天for (int i = 0; i < 6; i++) {//显示边框printf(": ");//显示日期part(year, month1, &day1);//显示中间边框printf(" ");//显示日期part(year, month2, &day2);//显示边框printf(" :\n");}}//显示日期void part(int year, int month, int* day) {if (isleapyear(year)) {Month[2] = 29;}//第一天需要输入到对应的位置上if (*day == 1) {//判断给定年份的第一天的距1940年1月1日的总天数int sum = sumofday(year, month);//设置总天数对应星期几,星期一对应第2天int step = (sum + 1) % 7;for (int i = 0; i < 7; i++) {//非对应的地方输出空格if (step != 0) {step--;printf("");}//输出第一天的所在位置else {printf("%3d ", *day);(*day)++;}}}//之后直接累加天数即可else {for (int i = 0; i < 7; i++) {if (*day <= Month[month]) {printf("%3d ", *day);(*day)++;}//超过当月天数的不输出else {printf("");}}}}

1.2查询某月日历:

#pragma once#pragma oncevoid mouth(){int y, m, days, i, xq, ts, sum;system("cls");//clears 作用是让屏幕清干净printf("|----------------------------------------------|\n");printf("|----------当前功能为查看某月日历--------------|\n");printf("|----------------------------------------------|\n");printf("请你输入年份:");scanf_s("%d", &y);while (y 2040){printf("请重新输入正确的年份:");scanf_s("%d", &y);}printf("请你输入月份 :");scanf_s("%d", &m);while (m 12){printf("请重新输入正确的月份:");scanf_s("%d", &m);}days = 0;//计算从1900-1-1到输入的年月日之间一共有多少天,初始值为0//1 1900年到y-1之间的整年天数days = days + (y - 1 - 1900 + 1) * 365;for (i = 1900; i <= y - 1; i++){if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)days++;}//2 计算y年中1月到m-1月之间的整月天数for (i = 1; i = 3)days++;//3 加上y年m月的当月天数 1days = days + 1;xq = days % 7;//星期一星期二星期三……星期日//xq1234560//计算y年m月的天数 tsswitch (m){case 1:case 3:case 5:case 7:case 8:case 10: case 12:ts = 31; break;case 4:case 6:case 9:case 11:ts = 30; break;case 2:ts = 28; break;}if ((y % 4 == 0 && y % 100 != 0 || y % 400 == 0) && m == 2)ts = 29;for (i = 1; i <= 7; i++)printf("----");printf("\n");printf(" %d月\n", m);for (i = 1; i <= 7; i++)printf("----");printf("\n");//输出printf("SUN MON TUE WED THD FRI SAT\n");//输出1日之间可能的空格 4个空格为一组,xq组空格for (i = 1; i <= xq; i++)printf("");sum = xq;for (i = 1; i <= ts; i++){sum++;printf("%2d", i);if (sum % 7 == 0)printf("\n");}printf("\n");printf("\n");printf("\n");printf("|----------------------------------------------|\n");printf("|--------------按任意键回到主菜单--------------|\n");printf("|----------------------------------------------|\n");system("pause");}

1.3查询某天日历:

void day(){int y1, y2, m1, m2, d1, d2, days1, days2, i, daysum, xingqi, a, b, F = 0;system("cls");//clears 作用是让屏幕清干净printf("|----------------------------------------------|\n");printf("|------前功能为查看某天日期及是否为节假日------|\n");printf("|----------------------------------------------|\n");printf("请你输入年份:");scanf_s("%d", &y1);while (y1 2040){printf("请重新输入正确的年份:");scanf_s("%d", &y1);}printf("请你输入月份 :");scanf_s("%d", &m1);while (m1 12){printf("请重新输入正确的月份:");scanf_s("%d", &m1);}printf("请你输入日期 :");scanf_s("%d", &d1);while (d1 31){printf("请重新输入正确的日期:");scanf_s("%d", &d1);}while (1){if ((y1 2040)){printf("提示:年份请输入1940年-2040年!\n ");printf("请重新输入正确的年份:");scanf_s("%d", &y1);continue;}else if (m1 12){printf("提示:月份请输入1-12月!\n ");printf("请重新输入正确的月份:");scanf_s("%d", &m1);continue;}else if ((m1 == 1 || m1 == 3 || m1 == 5 || m1 == 7 || m1 == 8 || m1 == 10 || m1 == 12) && (d1 31)){printf("提示:大月最多有31天!\n ");printf("请你按xxxx/xx/xx的格式重新输入正确的年月日: ");scanf_s("%d/%d/%d", &y1, &m1, &d1);continue;}else if ((y1 2040) || (m1 == 3 || m1 == 6 || m1 == 9 || m1 == 11) && (d1 30)){printf("提示:大月最多有31天!\n ");printf("请重新输入正确的日期:");scanf_s("%d", &d1);continue;}else if ((y1 2040) || (y1 % 4 == 0 && y1 % 100 != 0 || y1 % 400 == 0) && m1 == 2 && d1 > 29){printf("提示:闰年的2月份最多只有29天!\n ");printf("请重新输入正确的日期:");scanf_s("%d", &d1);continue;}else if ((y1 2040) || !(y1 % 4 == 0 && y1 % 100 != 0 || y1 % 400 == 0) && m1 == 2 && d1 > 28){printf("提示:平年的2月份最多只有28天!\n ");printf("请重新输入正确的日期:");scanf_s("%d", &d1);continue;}break;}a = m1, b = d1;{time_t timep;struct tm t;time(&timep);//获取系统日期和时间localtime_s(&t, &timep);y2 = 1900 + t.tm_year;//获取当前年份,从1900开始,所以要加1900m2 = 1 + t.tm_mon; //获取当前月份,范围是0-11,所以要加1d2 = t.tm_mday;//获取当前月份日数,范围是1-31}//获取系统日期days1 = 0;//计算从1-1-1到输入的年月日之间一共有多少天,初始值为0//1 1年到y-1之间的整年天数days1 = days1 + (y1 - 1) * 365;for (i = 1; i <= y1 - 1; i++)if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)days1++;//2 计算y1年中1月到m1-1月之间的整月天数for (i = 1; i = 3)days1++;//3 加上y1年m1月的当月天数 d1days1 = days1 + d1;//--------------------------------------------------------------------------------days2 = 0;//计算从1-1-1到当前的年月日之间一共有多少天,初始值为0//1 1年到y-1之间的整年天数days2 = days2 + (y2 - 1) * 365;for (i = 1; i <= y2 - 1; i++)if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)days2++;//2 计算y2年中1月到m2-1月之间的整月天数for (i = 1; i = 3)days2++;//3 加上y2年m2月的当月天数 d2days2 = days2 + d2;daysum = abs(days2 - days1);printf("%d年%d月%d日距今天有%d天,", y1, m1, d1, daysum);int days;days = 0;//计算从1900-1-1到输入的年月日之间一共有多少天,初始值为0//1 1900年到y-1之间的整年天数days = days + (y1 - 1 - 1900 + 1) * 365;for (i = 1900; i <= y1 - 1; i++){if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)days++;}//2 计算y年中1月到m-1月之间的整月天数for (i = 1; i = 3)days++;//3 加上y年m月的当月天数 1days = days + d1;xingqi = days % 7;switch (xingqi){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;}if (a == 1 && b == 1){printf("元旦节\n");F = 1;}if (a == 5 && b == 4){printf("青年节\n");F = 1;}if (a == 3 && b == 8){printf("妇女节\n");F = 1;}if (a == 9 && b == 10){printf("教师节\n");F = 1;}if (a == 5 && b == 1){printf("劳动节\n");F = 1;}if (a == 6 && b == 1){printf("儿童节\n");F = 1;}if (a == 7 && b == 1){printf("建党节\n");F = 1;}if (a == 3 && b == 12){printf("植树节\n");F = 1;}if (a == 8 && b == 1){printf("建军节\n");F = 1;}if (a == 10 && b == 1){printf("国庆节\n");F = 1;}if (F == 0)printf("不是节假日\n");printf("\n");printf("\n");printf("|----------------------------------------------|\n");printf("|--------------按任意键回到主菜单--------------|\n");printf("|----------------------------------------------|\n");system("pause");}

系统运行结果:

1.0主菜单:

1.1输出某年的日历:

1.2输出某月的日历:

1.3输入年月日输出距今天还有多少天,星期几,是否是公历节日: