linux下c/c++实例之一万年历

来源:互联网 时间:1970-01-01

一、简介

      Linux系统自带万年历程序,可以使用cal 11 2015命令查看11月份的日历。

二、详解

1、代码一

(1)calendar.c:

#include <stdio.h>#include <stdlib.h>#include <string.h>int main(int argc, char **argv){ if (argc != 2) { printf("usage: [%s 2000/10/1] or [%s 2000/10]/n", argv[0], argv[0]); return -1; } int year = 0, month = 0, day = 0, week = 0, days = 0; int i = 0; int flag = -1; //分隔年月日 int dm = 0; //月不同,与标准天的星期1-7天数的偏差 int dy = 0; //年不同,引起的星期1-7天数的偏差 int m2 = 0; //2月,引起的星期1-7天数的偏差 char WEEK[9] = {0}; while(argv[1][i]) { /*遍历传入的参数日期,计算出year,month,day*/ if ((argv[1][i] == '/' || argv[1][i] == '.' || argv[1][i] == '-') && flag == -1 ) { flag = 0; i++; continue; } if ((argv[1][i] == '/' || argv[1][i] == '.' || argv[1][i] == '-') && flag == 0 ) { flag = 1; i++; continue; } if (flag == -1) year = year * 10 + (argv[1][i] - '0'); if (flag == 0) month = month * 10 + (argv[1][i] - '0'); if (flag == 1) day = day * 10 + (argv[1][i] - '0'); i++; } if (month < 1 || month > 12 || year < 0) { /*若月份传入错误数字*/ printf ("ERROR! the entered MONTH or YEAR is invalid/n"); return -1; } if (year == 2000) { dy = 0; //以2000/1/1为基准点 m2 = 1; //29天 } else { /*** 该年 1月1号 到2000年1月1号的 " 天数差 " ***/ if(year > 2000) dy =(year -2000 ) + (year-1-2000)/4 - (year-1-2000)/100 + (year-1-2000)/400 + 1; else dy =(year -2000 ) + (year-2000)/4 - (year-2000)/100 + (year-2000)/400; if((year%4 == 0 && year%100 != 0) || (year%100 == 0 && year%400 == 0)) m2 = 1; else m2 = 0; /***该年不是润年***/ } switch (month) { case 1: dm = 0; days = 31; break; //31%7 == 3得偏移天数 case 2: dm = 3; days = (m2 == 1 ? 29 : 28); break; case 3: dm = 3 + m2; days = 31; break; case 4: dm = 6 + m2; days = 30; break; case 5: dm = 1 + m2; days = 31; break; case 6: dm = 4 + m2; days = 30; break; case 7: dm = 6 + m2; days = 31; break; case 8: dm = 2 + m2; days = 31; break; case 9: dm = 5 + m2; days = 30; break; case 10: dm = m2; days = 31; break; case 11: dm = 3 + m2; days= 30; break; case 12: dm = 5 + m2; days = 31; break; } if (day < 0 || day > days) { printf ("ERROR! the entered DAY is invalid/n"); exit (0); } week = (dy + dm + day - 1 + 6) % 7; if (week < 0) week += 7; if (day > 0) { /*** 判定查看类型 ***/ switch (week) { case 0: strcpy (WEEK,"SUNDAY"); break; case 1: strcpy (WEEK,"MONDAY"); break; case 2: strcpy (WEEK,"TUESDAY"); break; case 3: strcpy (WEEK,"WEDNESDAY"); break; case 4: strcpy (WEEK,"THURSDAY"); break; case 5: strcpy (WEEK,"FRIDAY"); break; case 6: strcpy (WEEK,"SATURDAY"); break; } printf ("this day is %s[%d]/nOK!/n", WEEK, week); } else { week = (++week ) % 7; printf ("the calender of this month as following/n"); printf ("/n*********************************/n"); printf (" SUN MON TUE WEN THU FRI STA/n"); for (i = 0; i < week; i++) printf (" "); for (i = 1; i <= days; i++) { printf (" %2d ",i); week++; if (week % 7 == 0 && i != days) printf ("/n"); } printf ("/n*********************************/n"); printf ("OK!/n"); } return 0;}
(2)编译运行
gcc -o calendar calendar.c
./calendar 2015/11

./calendar 2015/11/4

2、代码二

(1)calendar.c:
/* * cal.c * * Created on: Apr 10, 2011 * Author: Administrator * * 现行的格里历是从儒略历演化而来的。儒略历每4年一个润年,润年366天,平年365天。 * 如果从公元1年算的话,那么凡是能够被4整除的都是润年。从天文角度看,儒略历这种 * 历法是有误差的,到16世纪误差已经达到了10天。1582年,罗马教皇对儒略历进行了 * 一次校定,该年的10-5到10-14这10天被抹掉,并规定凡不能被400整除的世纪年不再 * 算为润年,校定之后的儒略历即为现行的格里历。 * * 但是英国直到1752年才开始使用格里历,此时时间误差已经达到了11天,原因是1700 * 年在儒略历中是润年,而在格里历中是平年。1752年英国议会决定将本年的9-3到9-13 * 这11天抹掉,以同步格里历。当时美国不是英国的殖民地,所以在美国的日历中也是没有 * 1752-9-3到1752-9-13这11天的。 我们知道UNIX系统源于美国,Linux系统源于UNIX, * 这就是为什么当我们在Linux系统中敲"cal 9 1752"这条命令时,会看到一个只有19天 * 的9月。 * * 以上内容参考自维基百科 * * 本程序模似Linux中cal命令的部分功能。允许输入的年分为1...9999。 * 编译器:gcc V4.5.0 * * 分析: * 1752年是特殊年,1752-9月是特殊年中的特殊月。 * * 1752-9-2之前,采用的是儒略历,凡能被4整除都为润年;1752-9-14之后,采用的是 * 格里历,不能被400整除的世纪年不再作为润年。 * * 格里历闰年计算方法 * 世纪年 ***4000的倍数 **3200/1900的倍数 400的倍数 100的倍数 4的倍数 * 结果 不闰 不闰 闰 不闰 闰 * 注: * 3200/1900的倍数是天文科学家研究出来 * 增加4000的倍数不闰更准确,但目前只是世纪年还不足4000,因此尚未用途 * * 格里历在400年的周期中有146,097天,恰好是20,871 星期。所以,例如,格里历七年、 * 407年、807年、1207年、1607年、2007年的日期与星期是完全相同的。也就是说,格里 * 历每400年一个周期。 * * 公元1-1-1,按儒略历是周六,按格里历是周一;因1752-9-2之前采用的都是儒略历,所以 * 公元1-1-1应该是周六。 * 1752-9-14是周四。 * * 公元1-1-1到1752-9-2,日期是连续的,儒略历;公元1752-9-14至今,日期是连续的,格里历。 * * 对于给定的一个 年(Y)-月(M)-日(D) ,则从公元1-1-1到 给定的日期的天数为: * 1752-9-2前:365*(Y-1)+(Y-1)/4+e,其中e表示从Y-1-1到Y-M-D的天数, * 且这天是该周的第((Y-1)+(Y-1)/4+5+e)%7天。 * * 1752-9-14后:365*(Y-1)+(Y-1)/4-(Y-1)/100+(Y-1)/400+e, * 且这天是该周的第((Y-1)+(Y-1)/4-(Y-1)/100+(Y-1)/400+e)%7天。 * * 需要注意的是,从1-1-1到1752-9-14之后的某个日期的天数并非实际的天数,它只是根据格里历的 * 的规则推算出来的,目的也只是为了得到日期与星期的对应。 * * 算法思想: * 对于年历,若能知道本年的1月1日是周几,也就知道了本年的年历分布。 * 对于月历,若能知道本月的1日是周几,也就知道了本月的月历分布。 * 所以关键是正确的推算出给定的一个日期是星期几。以下为推算方法: * 1752-9-2之前:((Y-1)+(Y-1)/4+5+e)%7 * 1752-9-14之后:((Y-1)+(Y-1)/4-(Y-1)/100+(Y-1)/400+e)%7 * 把1800-2199年当成一个周期,对于其后的日期,只需在1800-2199之间找到 * 对应的日期,就可以知道是星期几,这样就不用再考虑4000年之后4000的倍数 * 不是润年这种情况。 (Y-1800)%400+1800 * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>static void PrintHelp();static int* CurrentCal();static int CheckYear(int year);static int CheckMonth(int month);static int CheckDay(int year, int month, int day);static int IsNum(char *argv);static int IsLegalParameter(int argc, char **argv);static long StrToLong(char *argv);static long Power(int baseNumber, int exponent);static void PrintCalendar(int year);static void PrintCommonCalendar(int year, int row);static void PrintOneQuarter(int year, int mfOfWeek, int mfDays, int msOfWeek, int msDays, int mtOfWeek, int mtDays, int row);static void Print1752_3Quarter();static void PrintMonthlyCalendar(int year, int month);static void PrintMonthName(char *, int year);static void PrintCommonMonthlyCalendar(int dayOfWeek, int days);static void PrintDayOfWeek(int year, int month, int day);static int DayOfWeek(int year, int month, int day);int CurrentDays(int year, int month, int day);int len_year = 0; //输入的年这个参数的字符串长度,主根用于后面的PrintMonthName(char *, int)函数int cal[3] = {0};int main(int argc, char **argv){ int year = 0, month = 0, day = 0; int flag = IsLegalParameter(argc, argv); switch(flag) { case -1: printf("Syntax Error!/n/n"); PrintHelp(); break; case 0: PrintMonthlyCalendar(*(CurrentCal()), *(CurrentCal() + 1)); break; case 1: { len_year = strlen(*(argv + 1)); switch(argc) { case 2: year = StrToLong(*(argv + 1)); if (!CheckYear(year)) break; printf(" %4d/n/n", year); PrintCalendar(year); break; case 3: year = StrToLong(*(argv + 1)); if (!CheckYear(year)) break; month = StrToLong(*(argv + 2)); if (!CheckMonth(month)) break; PrintMonthlyCalendar(year, month); break; case 4: year = StrToLong(*(argv + 1)); if (!CheckYear(year)) break; month = StrToLong(*(argv + 2)); if (!CheckMonth(month)) break; day = StrToLong(*(argv + 3)); if (!CheckDay(year, month, day)) break; PrintDayOfWeek(year, month, day); break; default: year = StrToLong(*(argv + 1)); if (!CheckYear(year)) break; month = StrToLong(*(argv + 2)); if (!CheckMonth(month)) break; day = StrToLong(*(argv + 3)); if (!CheckDay(year, month, day)) break; PrintDayOfWeek(year, month, day); break; } break; } default: break; } return 0;}void PrintHelp(){ printf("usage:cal [<YEAR> [<MONTH> [<DAY>]]");}/* *以下函数判断输入的参数是否合法 */int IsLegalParameter(int argc, char **argv) { if (argc == 1) { return 0; //0表示没有输入参数 } while (argc > 1) { if (!IsNum(*(argv + --argc))) { return -1; //-1表示输入的参数不合法 } } return 1; //1表示输入了参数,并且参数是合法的}/* * 以下函数判断一个字符串是否能被转换成数字 */int IsNum(char *argv) { while (*argv != '/0') { if (*argv >= 48 && *argv <= 57) { argv++; continue; } return 0; } return 1;}/** * 以下函数返回一个包含当前年 月 日的整型数组 */int* CurrentCal(){ time_t nowtime; struct tm *timeinfo; time(&nowtime); timeinfo = localtime(&nowtime); memset(cal, 0, sizeof(cal)); cal[0] = timeinfo->tm_year + 1900; cal[1] = timeinfo->tm_mon + 1; cal[2] = timeinfo->tm_mday; //printf("data=%d, %d, %d/n", cal[0], cal[1], cal[2]); return cal;}/** * 打印指定月的月历 */void PrintMonthlyCalendar(int year, int month){ int dayOfWeek = DayOfWeek(year, month, 1); switch (month) { case 1: PrintMonthName("January", year); PrintCommonMonthlyCalendar(dayOfWeek, 31); break; case 2: PrintMonthName("February", year); if (year < 1753 && year % 4 == 0) { PrintCommonMonthlyCalendar(dayOfWeek, 29); break; } else if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { PrintCommonMonthlyCalendar(dayOfWeek, 29); break; } PrintCommonMonthlyCalendar(dayOfWeek, 28); break; case 3: PrintMonthName("March", year); PrintCommonMonthlyCalendar(dayOfWeek, 31); break; case 4: PrintMonthName("April", year); PrintCommonMonthlyCalendar(dayOfWeek, 30); break; case 5: PrintMonthName("May", year); PrintCommonMonthlyCalendar(dayOfWeek, 31); break; case 6: PrintMonthName("June", year); PrintCommonMonthlyCalendar(dayOfWeek, 30); break; case 7: PrintMonthName("July", year); PrintCommonMonthlyCalendar(dayOfWeek, 31); break; case 8: PrintMonthName("August", year); PrintCommonMonthlyCalendar(dayOfWeek, 31); break; case 9: PrintMonthName("September", year); if (year == 1752) { //特殊的1752-9 printf("Su Mo Tu We Th Fr Sa/n 1 2 14 15 16/n17 18 19 20 21 22 23/n24 25 26 27 28 29 30/n"); break; } PrintCommonMonthlyCalendar(dayOfWeek, 30); break; case 10: PrintMonthName("October", year); PrintCommonMonthlyCalendar(dayOfWeek, 31); break; case 11: PrintMonthName("November", year); PrintCommonMonthlyCalendar(dayOfWeek, 30); break; case 12: PrintMonthName("December", year); PrintCommonMonthlyCalendar(dayOfWeek, 31); break; default: break; }}/** * 以下函数返回给定的年、月、日是周几 */int DayOfWeek(int year, int month, int day){ if ((year < 1752) || (year == 1752 && month < 9) || (year == 1752 && month == 9 && day < 3)) { return ((year - 1) + (year - 1) / 4 + CurrentDays(year, month, day) + 5) % 7; } if (year == 1752 && month == 9 && (day > 2 && day < 14)) { printf("本万年历中没有%d-%d-%d这一天/n", year, month, day); return -1; } if (year > 2199) { year = (year - 1800) % 400 + 1800; } return ((year - 1) + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400 + CurrentDays(year, month, day)) % 7;}/** * 以下函数计算从给定年的1-1到month-day的天数 */int CurrentDays(int year, int month, int day){ int days = 0; switch(month) { case 1: days = day; break; case 2: days = 31 + day; break; case 3: days = 59 + day; break; case 4: days = 90 + day; break; case 5: days = 120 + day; break; case 6: days = 151 + day; break; case 7: days = 181 + day; break; case 8: days = 212 + day; break; case 9: days = 243 + day; break; case 10: days = 273 + day; break; case 11: days = 304 + day; break; case 12: days = 334 + day; break; default: break; } if (year < 1753 && year % 4 == 0) { if (month > 2) ++days; } else if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { if (month > 2) ++days; } return days;}/** * 以下函数的作用仅仅是将月名在水平方向上打印到月历的中间 */void PrintMonthName(char *monthName, int year){ char space = 32; int preSpaces = 0; preSpaces = (21 - strlen(monthName) - len_year - 1) / 2; printf("%*c%s %d/n", preSpaces, space, monthName, year); printf("--------------------/n");}/** * 根据一个月的天数及该月有几天这两个参数,打印出该月的月历 */void PrintCommonMonthlyCalendar(int dayOfWeek, int days){ int i, j, day = 1; char space = 32; int weeks = (days + dayOfWeek) / 7 + 1; //计算出该月有几周 printf("Su Mo Tu We Th Fr Sa/n"); printf("%*c", 3 * dayOfWeek, space); for (i = 0; i < weeks; ++i) { if (i == 0) { //打印第1周 for (j = dayOfWeek; j < 7; ++j) { printf("%2d ", day); day++; } continue; } //打印第2周到倒数第2周 if (i < weeks - 1) { printf("/n%2d %2d %2d %2d %2d %2d %2d", day, day + 1, day + 2, day + 3, day + 4, day + 5, day + 6); day += 7; continue; } //打印最后一周 printf("/n"); for (j = 0; j < 7; ++j) { if (day <= days) { printf("%2d ", day++); } } printf("/n"); }}/** * 以下函数将一个字符串转换成数字。 */long StrToLong(char *argv){ if (!IsNum(argv)) { return 0; } long result = 0; int argvLength = strlen(argv); int *nums = (int *)malloc((argvLength + 1) * sizeof(int)); memset(nums, 0, (argvLength + 1) * sizeof(int)); //int nums[1000] = {0}; int *pInt = nums; int i = 0; do { *(pInt++) = *argv - 48; int num = *argv - 48; argv++; } while(*argv != '/0'); pInt = nums; do { result += *pInt * Power(10, argvLength - 1); pInt++; argvLength--; } while (argvLength != 0); free(nums); return result;}/* * According to the base number and the exponent calculate power. * 根据基数和指数,计算出乘方数。 */long Power(int baseNumber, int exponent){ long result = 1; if (exponent == 0) { return 1; } do { result *= baseNumber; exponent--; } while (exponent != 0); return result;}int CheckYear(int year){ if (year == 0 || year > 9999) { printf("cal: year %d not in range 1..9999/n", year); return 0; } return 1;}int CheckMonth(int month) { if (month < 1 || month > 12) { printf("cal: month %d not in range (1..12)/n", month); return 0; } return 1;}int CheckDay(int year, int month, int day) { switch (month) { case 1: if (day < 1 || day > 31) { printf("cal: day %d not in range (1..31)/n", day); return 0; } return 1; break; case 2: if ((year < 1753 && year % 4 == 0) || ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) { if (day < 1 || day > 29) { printf("cal: day %d not in range (1..29)/n", day); return 0; } } if (day < 1 || day > 28) { printf("cal: day %d not in range (1..28)/n", day); return 0; } return 1; break; case 3: if (day < 1 || day > 31) { printf("cal: day %d not in range (1..31)/n", day); return 0; } return 1; break; case 4: if (day < 1 || day > 30) { printf("cal: day %d not in range (1..30)/n", day); return 0; } return 1; break; case 5: if (day < 1 || day > 31) { printf("cal: day %d not in range (1..31)/n", day); return 0; } return 1; break; case 6: if (day < 1 || day > 30) { printf("cal: day %d not in range (1..30)/n", day); return 0; } return 1; break; case 7: if (day < 1 || day > 31) { printf("cal: day %d not in range (1..31)/n", day); return 0; } return 1; break; case 8: if (day < 1 || day > 31) { printf("cal: day %d not in range (1..31)/n", day); return 0; } return 1; break; case 9: if (day < 1 || day > 30) { printf("cal: day %d not in range (1..30)/n", day); return 0; } return 1; break; case 10: if (day < 1 || day > 31) { printf("cal: day %d not in range (1..31)/n", day); return 0; } return 1; break; case 11: if (day < 1 || day > 30) { printf("cal: day %d not in range (1..30)/n", day); return 0; } return 1; break; case 12: if (day < 1 || day > 31) { printf("cal: day %d not in range (1..31)/n", day); return 0; } return 1; break; default: break; return 0; }}/** * 打印给定的年、月、日是周几 */void PrintDayOfWeek(int year, int month, int day){ char *names[9] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; int dayOfWeek = DayOfWeek(year, month, day); if (dayOfWeek == -1) return; printf("%d-%d-%d: %s/n", year, month, day, *(names + dayOfWeek));}/** * 以下函数打印年历,以月为单位,分成四行打印,每行打印三个月 */void PrintCalendar(int year){ int i; for (i = 0; i < 4; ++i) { switch (i) { case 0: //打印第1行,1-3月的月历 printf(" January February March/n"); printf("-------------------- -------------------- --------------------/n"); printf("Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa/n"); PrintCommonCalendar(year, 1); break; case 1: //打印第2行,4-6月的月历 printf(" April May June/n"); printf("-------------------- -------------------- --------------------/n"); printf("Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa/n"); PrintCommonCalendar(year, 2); break; case 2: //打印第3行,7-9月的月历 printf(" July August September/n"); printf("-------------------- -------------------- --------------------/n"); printf("Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa/n"); PrintCommonCalendar(year, 3); break; case 3: //打印第4行,11-12月的月历 printf(" October November December/n"); printf("-------------------- -------------------- --------------------/n"); printf("Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa/n"); PrintCommonCalendar(year, 4); break; default: break; } }}/** * 打印出给定年,给定行的3个月的月历。 */void PrintCommonCalendar(int year, int row){ int mfOfWeek, mfDays; //mfOfWeek表示该行第1个月的1号是周几,mfDays表示第1个月的天数 int msOfWeek, msDays; //mfOfWeek表示该行第2个月的1号是周几,mfDays表示第2个月的天数 int mtOfWeek, mtDays; //mfOfWeek表示该行第3个月的1号是周几,mfDays表示第3个月的天数 switch (row) { case 1: mfOfWeek = DayOfWeek(year, 1, 1); mfDays = 31; msOfWeek = DayOfWeek(year, 2, 1); msDays = 28; mtOfWeek = DayOfWeek(year, 3, 1); mtDays = 31; PrintOneQuarter(year, mfOfWeek, mfDays, msOfWeek, msDays, mtOfWeek, mtDays, row); break; case 2: mfOfWeek = DayOfWeek(year, 4, 1); mfDays = 30; msOfWeek = DayOfWeek(year, 5, 1); msDays = 31; mtOfWeek = DayOfWeek(year, 6, 1); mtDays = 30; PrintOneQuarter(year, mfOfWeek, mfDays, msOfWeek, msDays, mtOfWeek, mtDays, row); break; case 3: if (year == 1752) { Print1752_3Quarter(); break; } mfOfWeek = DayOfWeek(year, 7, 1); mfDays = 31; msOfWeek = DayOfWeek(year, 8, 1); msDays = 31; mtOfWeek = DayOfWeek(year, 9, 1); mtDays = 30; PrintOneQuarter(year, mfOfWeek, mfDays, msOfWeek, msDays, mtOfWeek, mtDays, row); break; case 4: mfOfWeek = DayOfWeek(year, 10, 1); mfDays = 31; msOfWeek = DayOfWeek(year, 11, 1); msDays = 30; mtOfWeek = DayOfWeek(year, 12, 1); mtDays = 31; PrintOneQuarter(year, mfOfWeek, mfDays, msOfWeek, msDays, mtOfWeek, mtDays, row); break; default: break; }}/** * 以下函数打印一个季度,也即是在同一行上的3个月的月历。 * * 打印方式肯定是从上到下,从左到右依次打印。 * * 每月至多有6周,至少有5周;第1周、第5周和第6周(如果有第6周)是需要特殊处理 * 的三个周,因为这3周并不一定总是有7天。 */void PrintOneQuarter(int year, int mfOfWeek, int mfDays, int msOfWeek, int msDays, int mtOfWeek, int mtDays, int row){ int mfDay = 1, msDay = 1, mtDay = 1; //对已经打印的天数记数 int i, j; char space = 32; //如果要打印的是1-3月的月历,则应该判断一下该年的2月是29天不是29天 if (row == 1) { if ((year < 1753 && year % 4 == 0) || (year >= 1753 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))) { msDays = 29; } } for (i = 0; i < 6; ++i) { if (i == 0) { //输出第一个月的第一周 if (mfOfWeek > 0) { printf("%*c", 3 * mfOfWeek, space); } for (j = mfOfWeek; j < 7; ++j) { printf("%2d ", mfDay); mfDay++; } //输出第二个月的第一周 printf("%*c", 3 * msOfWeek + 1, space); for (j = msOfWeek; j < 7; ++j) { printf("%2d ", msDay); msDay++; } //输出第三个月的第一周 printf("%*c", 3 * mtOfWeek + 1, space); for (j = mtOfWeek; j < 7; ++j) { printf("%2d ", mtDay); mtDay++; } continue; } //打印2-4周 if (i < 4) { printf("/n%2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d", / mfDay, mfDay + 1, mfDay + 2, mfDay + 3, mfDay + 4, mfDay + 5, mfDay + 6, msDay, msDay + 1, msDay + 2, / msDay + 3, msDay + 4, msDay + 5, msDay + 6, mtDay, mtDay + 1, mtDay + 2, mtDay + 3, mtDay + 4, / mtDay + 5, mtDay + 6); mfDay += 7; msDay += 7; mtDay += 7; continue; } //打印第1个月的第5周或第6周 if (mfDays - mfDay > 6) { //未打印天数不少于7天时,能够占满1周,直接打印 printf("/n%2d %2d %2d %2d %2d %2d %2d ", mfDay, mfDay + 1, mfDay + 2, mfDay + 3, mfDay + 4, mfDay + 5, mfDay + 6); mfDay += 7; } else { //未打印天数不足一周时,按以下方式打印 printf("/n"); for (j = 0; j < 7; ++j) { //有数据打印数据,没有数据用空格填充 if (mfDay <= mfDays) { printf("%2d ", mfDay++); } else { printf(" "); } } } printf(" "); //打印第2个月的第5周或第6周 if (msDays - msDay > 6) { printf("%2d %2d %2d %2d %2d %2d %2d ", msDay, msDay + 1, msDay + 2, msDay + 3, msDay + 4, msDay + 5, msDay + 6); msDay += 7; } else { for (j = 0; j < 7; ++j) { if (msDay <= msDays) { printf("%2d ", msDay++); } else { printf(" "); } } } printf(" "); //打印第3个月的第5周或第6周 if (mtDays - mtDay > 6) { printf("%2d %2d %2d %2d %2d %2d %2d ", mtDay, mtDay + 1, mtDay + 2, mtDay + 3, mtDay + 4, mtDay + 5, mtDay + 6); mtDay += 7; } else { for (j = 0; j < 7; ++j) { if (mtDay <= mtDays) { printf("%2d ", mtDay++); } } } } printf("/n");}/** *特殊的1752年第3季度:7月8月9月 */void Print1752_3Quarter() { char space = 32; printf("%10c1 2 3 4%21c1%9c1 2 14 15 16/n", space, space, space); printf(" 5 6 7 8 9 10 11 2 3 4 5 6 7 8 17 18 19 20 21 22 23/n"); printf("12 13 14 15 16 17 18 9 10 11 12 13 14 15 24 25 26 27 28 29 30/n"); printf("19 20 21 22 23 24 25 16 17 18 19 20 21 22/n"); printf("26 27 28 29 30 31 23 24 25 26 27 28 29/n"); printf("%22c30 31/n", space);}
(2)编译运行:
gcc -o calendar calendar.c
./calendar(等同于./calendar 2015 11)

./calendar 2015


./calendar 2015 11 4

三、总结

(1)万年历的算法还是比较复杂的,需要考虑的因素比较多,也可看看linux系统的源码包util-linux-ng参考万年历的实现。
(2)若有建议,请留言,在此先感谢!



相关阅读:
Top