#include <iostream>
#include <iomanip>
#include <string>

using namespace std;

class Date {
public:
	// 默认构造函数,以fullyear的形式给出年月日,默认值为1990年1月1日,同时设置日期分隔符为“-”
	Date(int year = 1990, int month = 1, int day = 1, char separator = '-');

	// get、set方法
	// 设置日期,如果有非法的月或日,将其置为1
	void setDate(int year, int month, int day);
	int getYearDays(int year) const;

	void setYear(int year);
	void setMonth(int month);
	void setDay(int month);
	void setSeparator(char separator);

	int getYear() const;
	int getMonth() const;
	int getDay() const;
	char getSeparator() const;

	// 输出函数,请使用setfill('0')和setw(2)
	void printFullYear() const; // 以YYYY-MM-DD的形式打印,2011-01-08
	void printStandardYear() const; // 以YY-MM-DD的形式打印,比如11-01-08
	// 计算当前日期与参数日期之间相差几个整年,仅考虑参数日期比当前日期晚的情况
	int fullYearsTo(int year, int month, int day) const;
	int fullYearsTo(const Date& date) const;
	// 计算当前日期与参数日期之间相差多少天(考虑闰年),如果参数日期在当前日期之前,返回负数。
	int daysTo(int year, int month, int day) const;
	int getLeftDaysYear() const;

	int getDayOfYear() const;

	friend ostream & operator <<(ostream & output, const Date & date);
	friend istream & operator >>(istream & input, Date & date);
	int operator -(const Date & date) const;
	bool operator ==(const Date & date) const;
	const Date operator +=(int days);
	bool operator >(const Date & date) const;
	bool operator <(const Date & date) const;

private:
	int checkDay(int testDay) const;
	bool isLeapyear(int year) const;

private:
	int year;
	int month;
	int day;
	char separator; // 日期分隔符

	const static int DAYS_PER_MONTH[12];

};

istream & operator >>(istream & input, Date & date) {
	input >> date.year >> date.month >> date.day;

	return input;
}

ostream & operator<<(ostream & output, const Date & date) {
	output << date.year << '-' << date.month << '-' << date.day;
	return output;
}

const int Date::DAYS_PER_MONTH[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

Date::Date(int year, int month, int day, char separator) :
		year(year), month(month), day(day), separator(separator) {
}

void Date::setDate(int year, int month, int day) {
	this->year = year;
	this->month = month;
	this->day = day;
}

void Date::setYear(int year) {
	this->year = year;
}
void Date::setMonth(int month) {
	if (month >= 0 && month <= 12)
		this->month = month;
	else {
		this->month = 1;
		cout << "Invalid month (" << month << "), set to 1." << endl;
	}
}
void Date::setDay(int day) {
	this->day = checkDay(day); // validate the day.
}
void Date::setSeparator(char separator) {
	this->separator = separator;
}
int Date::getYear() const {
	return year;
}
int Date::getMonth() const {
	return month;
}
int Date::getDay() const {
	return day;
}
char Date::getSeparator() const {
	return separator;
}

//Print Date object in form YYYY-MM-DD
void Date::printFullYear() const {
	cout << year << separator << setfill('0') << setw(2) << month << separator << setw(2) << day << endl;
}

//Print Date object in form YY-MM-DD
void Date::printStandardYear() const {
	cout << setfill('0') << setw(2) << (year % 100) << separator << setw(2) << month << separator << setw(2) << day << endl;
}

// 计算当前日期与参数日期之间相差几个整年,注意参数为日期对象的引用
int Date::fullYearsTo(int year, int month, int day) const {
	// 如果当前日期的月小于参数日期的月;或者月相等,并且当前日期的日小于等于参数日期的日
	if ((this->month < month) || (this->month == month && this->day <= day))
		return year - this->year;
	else
		return year - this->year - 1;
}

int Date::fullYearsTo(const Date& date) const {
	// 如果当前日期的月小于参数日期的月;或者月相等,并且当前日期的日小于等于参数日期的日
	if ((month < date.month) || (month == date.month && day <= date.day))
		return date.year - year;
	else
		return date.year - year - 1;
}

// 重载减法运算符 -
// 计算当前日期比参数日期晚了多少天(考虑闰年)
// 如果参数日期晚于当前日期,返回负数,注意参数为日期对象的引用。
int Date::operator -(const Date & date) const {
	const Date *startDate; // 开始日期
	const Date *endDate; // 结束日期
	bool ascent = true; // 当前日期大于参数日期,则为真。默认为真。

	// 如果在同一年中
	if (year == date.year) {
		return getDayOfYear() - date.getDayOfYear();
	}

	// 不在同一年中,且当前日期大于参数日期
	if (year > date.year) {
		startDate = &date;
		endDate = this;
		// 如果当前日期早
	} else {
		startDate = this;
		endDate = &date;
		ascent = false;
	}

	// 先加上开始日期到该年结束的天数
	int offsetDays = startDate->getLeftDaysYear();

	// 再加上开始日期和结束日期之间的所有年的天数 (不包括起止年)
	for (int i = startDate->year + 1; i < endDate->year; i++) {
		offsetDays += getYearDays(i);
	}

	// 再加上结束日期时,该年已经过的天数
	offsetDays += endDate->getDayOfYear();

	// 如果是升序
	if (ascent)
		return offsetDays;
	// 如果是降序,返回负数
	else
		return 0 - offsetDays;
}

// 重载 > 运算符
bool Date::operator >(const Date & date) const {
	if (year == date.year) {
		if (month != date.month)
			return (month > date.month);
		else
			return (day > date.day);
	} else
		return (year > date.year);
}



// 计算某一年有多少天,闰年366天,平年365天
int Date::getYearDays(int year) const {
	if (isLeapyear(year))
		return 366;
	return 365;
}

// 计算当前日期距本年结束还有几天,不包括当前日期这一天
int Date::getLeftDaysYear() const {
	return getYearDays(year) - getDayOfYear();
}

bool Date::isLeapyear(int year) const {
	return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}

// utility function to confirm proper day value based on month and year; handle leap years, too.
int Date::checkDay(int testDay) const {
	if (testDay > 0 && testDay <= DAYS_PER_MONTH[month - 1])
		return testDay;

	if (isLeapyear(year) && month == 2 && testDay == 29)
		return testDay;

	cout << "Invalid day (" << testDay << ") set to 1.\n";
	return 1;
}

// 计算当前日期是本年的第几天
int Date::getDayOfYear() const {

	int days = 0; // 初始化

	// 加上从本年1月到当前日期前一月的所有天数(整月)
	for (int i = 1; i < month; i++) {
		days += DAYS_PER_MONTH[i - 1];
	}

	days += day; // 加上当前月的日子

	// 如果是闰年,并且当前日期大于等于2月,再加一天
	if (isLeapyear(year) && month > 2)
		days++;

	return days;
}

int Date::daysTo(int year, int month, int day) const {
	Date date(year, month, day);

	const Date *startDate; // 开始日期
	const Date *endDate; // 结束日期
	bool ascent = true; // 当前日期大于参数日期,则为真。默认为真。

	// 如果在同一年中
	if (this->year == year) {
		return getDayOfYear() - date.getDayOfYear();
	}

	// 不在同一年中,且当前日期大于参数日期
	if (this->year > year) {
		startDate = &date;
		endDate = this;
		// 如果当前日期早
	} else {
		startDate = this;
		endDate = &date;
		ascent = false;
	}

	// 先加上开始日期到该年结束的天数
	int offsetDays = startDate->getLeftDaysYear();

	// 再加上开始日期和结束日期之间的所有年的天数 (不包括起止年)
	for (int i = startDate->year + 1; i < endDate->year; i++)
		offsetDays += getYearDays(i);

	// 再加上结束日期时,该年已经过的天数
	offsetDays += endDate->getDayOfYear();

	// 如果是升序,返回负数
	if (ascent)
		return 0 - offsetDays;
	// 如果是降序
	else
		return offsetDays;
}

class Employee {
public:
	Employee(const string, const string, const Date &, const Date &);
	void print() const;
	const Date & getHireDate() const;

	// 计算员工在参数指定的日期时,满多少岁
	int getAge(const Date& date) const;

	// 计算该员工工作满了多少年
	int getYearsWorked(const Date& date) const;
	// 计算该员工工作了多少天
	int getDaysWorked(const Date& date) const;

	/* 参数: employees[]是雇员对象的数组;n是雇员对象数组的元素个数
	 * 返回值: 工作年限最长的雇员对象的引用 */
	static const Employee & getMostFaith(const Employee employees[], int n);

private:
	string firstName;
	string lastName;
	const Date birthDate; // composition: member object
	const Date hireDate;
};

Employee::Employee(const string first, const string last, const Date &dateOfBirth, const Date &dateOfHire) :
		firstName(first), lastName(last), birthDate(dateOfBirth), hireDate(dateOfHire) {
}

void Employee::print() const {
	cout << firstName << ' ' << lastName
			<< ", hire date: " << hireDate
			<< ", birthday: " << birthDate << endl;
}

const Date & Employee::getHireDate() const {
	return hireDate;
}

int Employee::getAge(const Date& date) const {
	return birthDate.fullYearsTo(date);
}

int Employee::getYearsWorked(const Date& date) const {
	return hireDate.fullYearsTo(date);
}

int Employee::getDaysWorked(const Date& date) const {
	return date - hireDate;
}

const Employee & Employee::getMostFaith(const Employee employees[], int n) {
	int index = 0;
	for (int i = 1; i < n; i++) {
		if (employees[index].getHireDate() > employees[i].getHireDate())
			index = i;
	}

	return employees[index];
}


int main() {
	const Employee employees[5] = {
		Employee("Pat",  "Hingle", Date(1965, 5, 11), Date(1998, 4, 17)),
		Employee("David", "Hodges", Date(1967, 7, 21), Date(1997, 5, 12)),
		Employee("Christian", "Bale", Date(1969, 8, 3), Date(1995, 12, 1)),
		Employee("Gus", "Lewis", Date(1970, 3, 1), Date(2000, 3, 7)),
		Employee("Aaron", "Eckhart", Date(1968, 4, 23), Date(1994, 10, 30))
	};

	const Employee & employee = Employee::getMostFaith(employees, 5);
	cout << "工作年限最长的雇员的信息如下:" << endl;
	employee.print();

	return 0;
}
分析这个代码的类图内容:类图如下:

![image.png](https://cdn.luogu.com.cn/upload/image_hosting/ed4c8zjl.png)

类图中包含了Date类和Employee类,其中Employee类使用了Date类作为成员对象。Date类具有私有成员变量year、month、day和separator,以及公有成员函数和友元函数。Employee类具有私有成员变量firstName、lastName、birthDate和hireDate,以及公有成员函数print、getAge、getYearsWorked、getDaysWorked和getMostFaith。其中getMostFaith为静态函数,可以通过类名直接调用。
C++ 日期和员工类实现:包含运算符重载和静态函数

原文地址: https://www.cveoy.top/t/topic/oeZm 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录