感觉写得有点别扭....
万年历...写得不好见谅哈
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;
}
}
}
date.cpp:
/**
* 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);
}
util.cpp:
/**
* 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);
}
}
主程序 Cal.cpp
/**
* 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;
}
}