感觉写得有点别扭....
万年历...写得不好见谅哈
calendar.cpp:
/** * File calendar.cpp, 2011.09.15 * define class Calendar * Copyright by Zhou Junjie, 2011~2012, SE, Digital Media, class2, 10389149 **/ #include "calendar.h" #include "util.h" #include "date.h" #include "dateFormatException.h" #include <string> #include <sstream> #include <iomanip> #include <memory> using namespace std; Calendar* Calendar::calendar = NULL; Calendar* Calendar::getInstance() { if (!calendar) { calendar = new Calendar(); return calendar; } else { return calendar; } } Calendar::~Calendar() { if (!calendar) { delete calendar; calendar = NULL; } } string Calendar::getMonthCalendar(int year, int month) { int maxMonthDays = 0; int firstDayWeek = 0; int dayCount = 0; try { maxMonthDays = maxMonthDay(year, month); firstDayWeek = dayWeek(year, month, 1); } catch (runtime_error) { throw; } ostringstream oss; oss << " " <<year << "-" << month << endl; oss << setw(4) << "日" << setw(4) << "一" << setw(4) << "二" << setw(4) << "三" << setw(4) << "四" << setw(4) << "五" << setw(4) << "六" << "\n"; // print the prefix blank for (int i = 0; i < firstDayWeek; i++) { oss << setw(4) << ""; dayCount++; } for (int i = 1; i <= maxMonthDays; i++) { oss << setw(4) << i; dayCount++; if (dayCount % 7 == 0) oss << "\n"; } return oss.str(); } string Calendar::getYearCalendar(int year) { ostringstream oss; oss << " " <<year << "年日历" << endl << endl; try { for (int month = 1; month <= 12; month++) { oss << this->getMonthCalendar(year, month) << endl << endl; } } catch (runtime_error) { throw; } return oss.str(); } int Calendar::calculateDayInterval(string firstDay, string secondDay) { tr1::shared_ptr<Date> firstDate = NULL; tr1::shared_ptr<Date> secondDate = NULL; try { firstDate = tr1::shared_ptr<Date>(Date::parse(firstDay)); secondDate = tr1::shared_ptr<Date>(Date::parse(secondDay)); } catch (DateFormatException) { throw; } return (*firstDate - *secondDate); } string Calendar::getDayOfWeek(int year, int month, int day) { if (!checkDayIfInvaild(year, month, day)) throw runtime_error("日期非法"); else { string weekDays[7] = {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY}; try { return weekDays[dayWeek(year, month, day) - 1]; } catch (runtime_error) { throw; } } }
/** * File date.cpp, 2011.09.16 * define class Date * Copyright by Zhou Junjie, 2011~2012, SE, Digital Media, class2, 10389149 **/ #include "date.h" #include "util.h" #include "dateFormatException.h" #include <iostream> #include <string> #include <vector> using namespace std; Date* Date::parse(string dateString) { vector<string> dateContent = split(dateString, "-"); if (dateContent.size() != 3) { throw DateFormatException("日期格式错误"); } else { int year = atoi(dateContent[0].c_str()); int month = atoi(dateContent[1].c_str()); int day = atoi(dateContent[2].c_str()); try { return new Date(year, month, day); } catch (runtime_error) { throw; } } } Date::Date(int year, int month, int day) { if (!checkDayIfInvaild(year, month, day)) throw runtime_error("日期非法"); this->year = year; this->month = month; this->day = day; } long long Date::operator-(Date& rightDate) { return abs(getDays() - rightDate.getDays()); } long long Date::getDays() { int leapYear = 0; int notLeapYear = 0; int totalMonthDays = 0; for (int i = 1900; i < year; i++) { if (isLeapYear(i)) leapYear++; else notLeapYear++; } for (int i = 1; i < month; i++) { totalMonthDays += maxMonthDay(year, month); } return (leapYear * 366 + notLeapYear * 365 + totalMonthDays + day); }
/** * File util.cpp, 2011.09.15 * Define the function in file util.h * Copyright by Zhou Junjie, 2011~2012, SE, Digital Media, class2, 10389149 **/ #include "util.h" #include <vector> #include <string> using namespace std; vector<string> split(string source, string sep) { vector<string> result; int sepLen = sep.length(); int lastPosition = 0; int index = -1; while (-1 != (index = source.find(sep, lastPosition))) { result.push_back(source.substr(lastPosition, index - lastPosition)); lastPosition = index + sepLen; } string lastString = source.substr(lastPosition); if (!lastString.empty()) { result.push_back(lastString); } return result; } bool checkDayIfInvaild(int year, int month, int day) { if (day < 1) return false; if ((year % 4 == 0 && year %100 !=0) || year % 400 == 0) { if (month == 2) { if (day > 29) { return false; } } } else { switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: if (!(day >=1 && day <= 31)) return false; break; case 4: case 6: case 9: case 11: if (!(day >= 1 && day <= 30)) return false; break; case 2: if (!(day >= 1 && day <= 28)) return false; break; } } return true; } bool isLeapYear(int year) { if ((year % 4 == 0 && year %100 !=0) || year % 400 == 0) return true; else return false; } int maxMonthDay(int year, int month) { if (month <=0 || month > 12) { throw runtime_error("月份错误"); } int monthDays[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; if (isLeapYear(year) && month == 2) return 29; else return monthDays[month - 1]; } int dayWeek(int year, int month, int day) { if (month <= 0 || month > 12) { throw runtime_error("月份错误"); } else if (day <= 0 || day > maxMonthDay(year, month)) { throw runtime_error("日期错误"); } else { int date = 0; float result = 0; for (int i = 1; i < month; i++) date += maxMonthDay(year, i); date += day; result = year - 1 + (float)(year - 1) / 4 + (float)(year - 1) / 100 + (float)(year - 1) / 400 - 40 + date; return ((int)result % 7); } }
/** * File Cal.cpp, 2011.09.17 * the main interface of this program * Copyright by Zhou Junjie, 2011~2012, SE, Digital Media, class2, 10389149 **/ #include "calendar.h" #include "dateFormatException.h" #include "util.h" #include <iostream> #include <sstream> #include <string> #include <memory> #include <ctime> using namespace std; string instrument(); string info(); void operation(int choice, tr1::shared_ptr<Calendar> calendar); int main() { cout << info() << endl; cout << instrument() << endl; tr1::shared_ptr<Calendar> calendar(Calendar::getInstance()); int choice; cin >> choice; while (true) { if (choice == 6) break; else { string yesOrNot = ""; operation(choice, calendar); cout << "是否继续?(y/n)" << endl; cin >> yesOrNot; if (yesOrNot == "y" || yesOrNot == "Y" || yesOrNot == "yes") { cout << instrument() << endl; cin >> choice; } else break; } } return 0; } string instrument() { ostringstream oss; oss << "请输入你的选择" << endl << "1.输出今年日历" << endl << "2.输出某一年的日历" << endl << "3.输出某一天是星期几" << endl << "4.输出两个日期之间相差多少天" << endl << "5.输出某一个月的月历" << endl << "6.退出" << endl; return oss.str(); } string info() { ostringstream oss; oss << "Calendar v1.0" << endl << "Copyright by Zhou Junjie, 2011~2012, Software Engineering, Digital Media" << endl; return oss.str(); } void operation(int choice, tr1::shared_ptr<Calendar> calendar) { switch (choice) { case 1: { time_t rawTime = time(NULL); tm* timePtr = localtime(&rawTime); int thisYear = timePtr->tm_year + 1900; try { cout << calendar->getYearCalendar(thisYear) << endl; } catch (runtime_error e) { cout << e.what() << endl; } } break; case 2: { int year; cout << "请输入年份" << endl; cin >> year; try { cout << calendar->getYearCalendar(year) << endl; } catch (runtime_error e) { cout << e.what() << endl; } } break; case 3: { string date; cout << "请输入日期(yyyy-MM-dd)" << endl; cin >> date; vector<string> dateContent = split(date, "-"); if (dateContent.size() != 3) { cout << "日期格式错误" << endl; break; } else { int year = atoi(dateContent[0].c_str()); int month = atoi(dateContent[1].c_str()); int day = atoi(dateContent[2].c_str()); try { cout << date << " 是 " << calendar->getDayOfWeek(year, month, day) << endl; } catch (runtime_error e) { cout << e.what() << endl; } } } break; case 4: { string firstDay = ""; string secondDay = ""; cout << "请输入第一个日期(yyyy-MM-dd)" << endl; cin >> firstDay; cout << "请输入第二个日期(yyyy-MM-dd)" << endl; cin >> secondDay; try { cout << firstDay << " 与 " << secondDay << " 相差 " << calendar->calculateDayInterval(firstDay, secondDay) << " 天" << endl; } catch (DateFormatException e) { cout << e.what() << endl; } } break; case 5: { int year; int month; cout << "请输入年份,月份" << endl; cin >> year >> month; try { cout << calendar->getMonthCalendar(year, month) << endl; } catch (runtime_error e) { cout << e.what() << endl; } } break; } }