数据结构作业—Calendar

感觉写得有点别扭....

万年历...写得不好见谅哈

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;
	}
}


你可能感兴趣的:(数据结构,Date,String,calendar,Class,作业)