// Calendar.cpp : 定义控制台应用程序的入口点。 /*------------------------------------------------------------------- * Purpose: * 打印日历,主函数值传进来年份的值则打印当前年份的日历 * 主函数传进来的是年月,则输出当月的日历 * 传进来的是年月日,则输出距今天还有多少天,星期几,是否是公历节日。 * Time: * 2010年10月13日 19:27:58 * * Author: * 张彦升 --------------------------------------------------------------------*/ #include "stdafx.h" #include <iostream> #include <string> #include <stdio.h> #include <time.h> #include "calendar.h" using std::cout; int main(int argc, char* argv[]) { us_int year = 0,mouth = 0,day = 0; switch(argc) { case 1: break; case 2: (year = (us_int)atoi(argv[1]))?1:exit(-1); break; case 3: (year = (us_int)atoi(argv[1]))?1:exit(-1); (mouth = (us_int)atoi(argv[2]))?1:exit(-1); break; case 4: (year = (us_int)atoi(argv[1]))?1:exit(-1); (mouth = (us_int)atoi(argv[2]))?1:exit(-1); (day = (us_int)atoi(argv[3]))?1:exit(-1); break; default: exit(-1); } Calendar CurCalendar(year,mouth,day); //这儿存在一个bug,当year被输入负数后,因其是unsigned型,强制转换成int型后将为65535,并不是负数,从而打印出的日历并不是默认的当年的日历 //Calendar CurCalendar(2010,6,23); CurCalendar.Printcalendar(); return 0; } /*------------------------------------------------------------------- * Purpose: * calendar.h中的函数进行初始化 * summarize: * 1,c++里也带了按一定格式输出的函数setw,其实完全不用printf就可以 * 2,全局变量作为函数参数是个危险家伙 * 3,错误信息应通过函数实现,相同的代码使代码剧增 * Time: * 2010年10月13日 21:04:13 * 2010年10月14日 22:31:05(rebuild) * Author: * 张彦升 --------------------------------------------------------------------*/ #include "stdafx.h" #include "calendar.h" #include <iostream> #include <string> #include <Windows.h> using std::cout; using std::endl; using std::string; #define puthead cout<<'|' #define putfoot cout<<" |" #define NL cout<<'/n' #define FESTIVAL_MAX 80 //there are 80 festival char Week[WEEKLENTH +1] = "SUN MON TUE WEN THU FRI SAT"; TagFestival festival[FESTIVAL_MAX] = { 1,1,"元旦", 2,2,"世界湿地节", 2,14,"情人节", 3,3, "全国爱耳节", 3,5,"青年志愿者服务节", 3,8, "国际妇女节", 3,9, "保护母亲河节", 3,12, "中国植树节v", 3,14, "白色情人节", 3,14, "国际警察节", 3,15, "世界消费者权益节", 3,21, "世界森林节", 3,21, "世界睡眠节", 3,22, "世界水节", 3,23, "世界气象节", 3,24, "世界防治结核病节", 4,1, "愚人节", 4,5, "清明节", 4,7,"世界卫生节", 4,22,"世界地球节", 4,26, "世界知识产权节", 5,1, "国际劳动节", 5,3, "世界哮喘节", 5,4, "中国青年节", 5,8, "世界红十字", 5,12, "国际护士节", 5,15, "国际家庭节", 5,17, "世界电信节", 5,20, "全国学生营养节", 5,23, "国际牛奶节", 5,31, "世界无烟节", 6,1, "国际儿童节", 6,5, "世界环境节", 6,6, "全国爱眼节", 6,17, "世界防治荒漠化和干旱节", 6,23, "国际奥林匹克节", 6,25, "全国土地节", 6,26, "国际禁毒节", 7,1, "中国共产党诞生节", 7,1, "国际建筑节", 7,7, "中国人民抗,战争纪念节", 7,11, "世界人口节", 8,1, "中国人民解放军建军节节", 8,12, "国际青年节", 9,8, "国际扫盲节", 9,10, "中国教师节", 9,16, "中国脑健康节", 9,16, "国际臭氧层保护节", 9,20, "全国爱牙节", 9,21, "世界停火节", 9,27, "世界旅游节", 10,1, "中华人民共和国国庆节", 10,1, "国际音乐节", 10,1, "国际老年人节", 10,4, "世界动物节", 10,5, "世界教师节", 10,8, "全国高血压节", 10,9, "世界邮政节", 10,10, "世界精神卫生节", 10,14, "世界标准节", 10,15, "国际盲人节节", 10,15, "世界农村妇女节", 10,16, "世界粮食节", 10,17, "国际消除贫困节", 10,24, "联合国节", 10,24, "世界发展新闻节", 10,28, "中国男性健康节", 10,29, "国际生物多样性节", 10,31, "万圣节节", 11,8, "中国记者节", 11,9, "消防宣传节", 11,14, "世界糖尿病节", 11,17, "国际大学生节", 11,25, "国际消除对妇女的暴力节", 12,1, "世界爱滋病节", 12,3, "世界残疾人节", 12,4, "全国法制宣传节", 12,9, "世界足球节", 12,25, "圣诞节", 12,29, "国际生物多样性节" }; char WeekDay[7][7] = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" }; Calendar::Calendar(us_int year,us_int month,us_int day) { Year_4 = year; Month_2 = month; Day_2 = day; if (0 == Year_4) //如果什么都没有输入的话,则默认是在当前年份下 { SYSTEMTIME st; GetLocalTime(&st); Year_4 = st.wYear; /************************************************************************/ /* There some question why use time_t and struct tm can't get the correct time /* time_t x = time(NULL); tm *local = localtime(&x); cout<<local->tm_mon; //why it is putout 9,it's OCT already /************************************************************************/ } return; } Calendar::~Calendar() { return; } int Calendar::InitMonthInfo(struct MonthInfo *sm) { for (us_int MonthIndex = 1;MonthIndex <= 12;MonthIndex ++) { us_int TempIndex = MonthIndex; us_int TempYear = Year_4; //当运用全局变量的时候而又不想改变该变量的值,一定要把全局变量作为一个临时变量来用 AdjustDate(TempYear,TempIndex); sm[MonthIndex -1].RelationDay = sm[MonthIndex -1].FirstDay = AdjustWeek(GetWeek(TempYear,TempIndex)); sm[MonthIndex -1].rt = 1; switch(MonthIndex) { case 1: sm[MonthIndex -1].Days = 31; break; case 2: sm[MonthIndex -1].Days = IsLeapYear(Year_4)?28:29; break; case 3: sm[MonthIndex -1].Days = 31; break; case 4: sm[MonthIndex -1].Days = 30; break; case 5: sm[MonthIndex -1].Days = 31; break; case 6: sm[MonthIndex -1].Days = 30; break; case 7: sm[MonthIndex -1].Days = 31; break; case 8: sm[MonthIndex -1].Days = 31; break; case 9: sm[MonthIndex -1].Days = 30; break; case 10: sm[MonthIndex -1].Days = 31; break; case 11: sm[MonthIndex -1].Days = 30; break; case 12: sm[MonthIndex -1].Days = 31; break; } } return 0; } int Calendar::PrintLine(us_int MonthIndex) { if (MonthIndex <= 6) { if (Month[MonthIndex -1].rt > Month[MonthIndex -1].Days) { printf("%*c",TATALLENGH,' '); } else { printf("%*d",(Month[MonthIndex -1].RelationDay*4 + OFFSETGAP + 4-1),Month[MonthIndex -1].rt++); while (++Month[MonthIndex -1].RelationDay < 7&& Month[MonthIndex -1].rt <= Month[MonthIndex -1].Days) { printf("%4d",Month[MonthIndex -1].rt++); } /*将空位补齐*/ Month[MonthIndex -1].RelationDay %= 7; if (0 != Month[MonthIndex -1].RelationDay &&Month[MonthIndex -1].RelationDay <= 6 ) { printf("%*c",(7 - Month[MonthIndex -1].RelationDay) *4,' '); } } } else { if (Month[MonthIndex -1].rt > Month[MonthIndex -1].Days) { printf("%*c",TATALLENGH ,' '); } else { printf("%*d",(Month[MonthIndex -1].RelationDay*4 +OFFSETGAP +4-1),Month[MonthIndex -1].rt++); while (++Month[MonthIndex -1].RelationDay < 7&& Month[MonthIndex -1].rt <= Month[MonthIndex -1].Days) { printf("%4d",Month[MonthIndex -1].rt++); } /*将空位补齐*/ Month[MonthIndex -1].RelationDay %= 7; if (0 != Month[MonthIndex -1].RelationDay &&Month[MonthIndex -1].RelationDay <= 6 ) { printf("%*c",(7 - Month[MonthIndex -1].RelationDay) *4,' '); } } } return 0; } int Calendar::Printcalendar() { InitMonthInfo(Month); if (0 == Month_2 && 0== Day_2) //若关于month与day的信息没有读取 { if ((int)Year_4 <= 0) { SetTextColor(0x0c); cout << "illegality input";NL; //退出并初始化为零 Restore; return 0; } NL;NL; NL; SetTextColor(0x0c);puthead; printf("===================The Calendar of year %d========================|",Year_4); Restore; NL; for(us_int CurMonthIndex = 1;CurMonthIndex <= 6;CurMonthIndex++) { SetTextColor(0x0c);puthead;Restore; SetTextColor(0x02); printf(" %02d %s",CurMonthIndex,Week); printf(" %02d %s",CurMonthIndex + 6,Week); Restore; SetTextColor(0x0c);putfoot;Restore; NL; for(us_int i = 1;i <=6;i++) { SetTextColor(0x0c);puthead;Restore; PrintLine(CurMonthIndex); PrintLine(CurMonthIndex +6); SetTextColor(0x0c);putfoot;Restore; NL; } } SetTextColor(0x0c);puthead; printf("====================================================================|"); Restore; NL; } else if (0 == Day_2) //若只有day的信息没有被读取 { if ((int)Month_2 <= 0 ||(int)Month_2 > 12) { SetTextColor(0x0c); cout << "illegality input";NL; Restore; return 0; } NL;NL; SetTextColor(0x0c);puthead; printf("======The Calendar of %04d/%02d======|",Year_4,Month_2); Restore; NL; SetTextColor(0x0c);puthead;Restore; SetTextColor(0x02); printf(" %02d %s",Month_2,Week); Restore; SetTextColor(0x0c);putfoot;Restore; NL; for (us_int i = 1;i <= 6;i++) { SetTextColor(0x0c);puthead;Restore; PrintLine(Month_2); SetTextColor(0x0c);putfoot;Restore; NL; } SetTextColor(0x0c);puthead; printf("===================================|"); Restore; NL; } else if(Year_4 && Month_2 && Day_2) //若三者的信息都被读取 { if ((int)Month_2 <= 0 ||(int)Month_2 > 12) { SetTextColor(0x0e); cout << "illegality input";NL; Restore; return 0; } if ((int)Day_2 <= 0 || Day_2 > Month[Month_2 -1].Days) { SetTextColor(0x0e); cout << "illegality input";NL; Restore; return 0; } SYSTEMTIME st; us_int Cur_year; us_int Cur_month; us_int Cur_day; int RangeDay = 0; us_int Temp_year = Year_4; us_int Temp_month = Month_2; us_int Temp_day = Day_2; int CurSum; int InputSum; GetLocalTime(&st); Cur_year = st.wYear; Cur_month = st.wMonth; Cur_day = st.wDay; InputSum = Year_4 + Month_2 * 100 + Day_2; //用三者的和做比较 CurSum = Cur_year + Cur_month * 100 + Cur_day; if (InputSum < CurSum) { while(Temp_year != Cur_year && Temp_year++ < Cur_year) { RangeDay += (int)IsLeapYear(Temp_year)?366:365; } while(Temp_month != 1 && --Temp_month >= 1) { RangeDay -= (int)Month[Temp_month -1].Days; } RangeDay -= (int)Day_2; Temp_year = Year_4; Year_4 = Cur_year; //因为我们要知道今年每月的天数,所以做临时将其保存 InitMonthInfo(Month); Year_4 = Temp_year; Temp_month = Cur_month; while (Temp_month != 1 && --Temp_month >= 1) { RangeDay += (int)Month[Temp_month -1].Days; } RangeDay += (int)Cur_day; NL; Temp_year = Year_4; Temp_month = Month_2; Temp_day = Day_2; AdjustDate(Temp_year,Temp_month); us_int Temp_week = (Temp_day + 2 * Temp_month + 3*( Temp_month+1)/5 + Temp_year + Temp_year/4 - Temp_year/100 + Temp_year/400) % 7 + 1; cout << "There are " << RangeDay << " days have gone"<<endl; SetTextColor(0x0e); cout << Month_2<<"月"<<Day_2<< "日:"<<'/t'; Restore; cout << WeekDay[Temp_week] <<'/t'; for (us_int i = 0;i < FESTIVAL_MAX;i++) { if (festival[i].Mouth == Month_2 && festival[i].Day == Day_2) { cout << festival[i].FestivalInfo <<endl; break; } } } else if (InputSum > CurSum) { while(Temp_year != Cur_year && --Temp_year <= Cur_year) { RangeDay += (int)IsLeapYear(Temp_year)?366:365; } while(Temp_month != 1 && --Temp_month >= 1) { RangeDay += (int)Month[Temp_month -1].Days; } RangeDay += (int)Day_2; Temp_year = Year_4; Year_4 = Cur_year; //因为我们要知道今年每月的天数,所以做临时将其保存 InitMonthInfo(Month); Year_4 = Temp_year; Temp_month = Cur_month; while (Temp_month != 1 && --Temp_month >= 1) { RangeDay -= (int)Month[Temp_month -1].Days; } RangeDay -= (int)Cur_day; NL; Temp_year = Year_4; Temp_month = Month_2; Temp_day = Day_2; AdjustDate(Temp_year,Temp_month); us_int Temp_week = (Temp_day + 2 * Temp_month + 3*( Temp_month+1)/5 + Temp_year + Temp_year/4 - Temp_year/100 + Temp_year/400) % 7 + 1; cout << "There are "<<RangeDay<<" days remain"<<endl; SetTextColor(0x0e); cout << Month_2<<"月 "<<Day_2<< "日:"<<'/t'; Restore; cout << WeekDay[Temp_week] <<'/t'; for (us_int i = 0;i < FESTIVAL_MAX;i++) { if (festival[i].Mouth == Month_2 && festival[i].Day == Day_2) { cout << festival[i].FestivalInfo <<endl; break; } } } } return 0; }
头文件
/*------------------------------------------------------------------- * Purpose: * calendar.h * calendar.c * Time: * 2010年10,13, 19:02:04 * * Author: * 张彦升 --------------------------------------------------------------------*/ #ifndef _CALENDAR_H #define _CALENDAR_H typedef unsigned short us_int; #ifndef EXPORT #define EXPORT extern "C" __declspec(dllexport) #endif //EXPORT #define OFFSETGAP 6 //间隙的长度 #define WEEKLENTH 27 //字符串week的长度 #define TATALLENGH ( OFFSETGAP + WEEKLENTH ) //一个,份占的一行的总长度 #define IsLeapYear(a) ( a%(a%100?4:400) ) //判断是否是闰年, retrun false is leap year #define AdjustDate(year,month) (month < 3?month +=12,year -=1:1 ) //调整年,,当是一,和二,的时候当作上一年的13,和14, #define GetWeek(year,month) ( (1 + 2 * month + 3*( month+1)/5 + year + year/4 - year/100 + year/400) % 7 + 1 ) //得到当,的第一天对应的星期 #define AdjustWeek(Index) ( Index == 7 ? 0:Index ) //调整为星期,为0, #define SetTextColor(a) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a) #define Restore SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0x0f) struct MonthInfo { us_int FirstDay; //当,第一天对应的星期(数字) us_int RelationDay; //关联相对应的星期 us_int rt; //关联打印辅助变量 us_int Days; //当,共有多少天 }; class Calendar { private: us_int Year_4; //存储年份 us_int Month_2; //month us_int Day_2; //day struct MonthInfo Month[12]; //存储一年内12个,的所有信息 public: Calendar(us_int year,us_int month,us_int day); //当输入情况下,得到年(和,,,) ~Calendar(); int Printcalendar(); int InitMonthInfo(struct MonthInfo *sm); int PrintLine(us_int MonthIndex); }; /************************************************************************/ /*the Gregorian calendar festival(GCF)公历节, /************************************************************************/ #ifndef __GCF #define __GCF struct TagFestival { us_int Mouth; us_int Day; char FestivalInfo[30]; }; #endif //__GCF #endif //_CALENDAR_H
测试文件