作为一个程序员,对于时间的概念已经退化到了三岁小孩水平,常常会醉心于写一个程序忘记了时间,一个下午,一天,甚至一个星期就过去了。对于一个刚入程序员大门的我来说,时光真的是匆匆溜走,所以经常会百度一个日期计数器,算今天到那些特别的日子还有多少天。用多了后就觉得现在储备的编程知识可以去实现一个简单的日期计算器了。所以就写了这篇博客给大家分享一下。
首先,得设计这个日期类,一个日期类应该具有私有数据成员应该有年Year,月month,日day。在这我们就不精确到时分秒了。
#pragma once #include<iostream> using namespace std; class Date { public: Date(int year, int month, int day); ~Date(); Date(const Date& a); void ShowDate(); bool operator==(const Date& d); bool operator<(const Date& d); bool operator<=(const Date& d); bool operator>(const Date& d); bool operator>=(const Date& d); Date operator+ (int day); Date& operator+= (int day); Date operator- (int day); Date& operator-= (int day); Date& operator++(); Date operator++(int); Date& operator--(); Date operator--(int); int operator-(const Date& d); friend ostream* operator<<(ostream* out, const Date &d); private: int GetMonthDay(int year, int month); bool IsLeapYear(int year); private: int _year; int _month; int _day; };
可以看到,一个日期类应该具有的功能大致上都有了。对于GetMonthDay()和IsLeapYear()是类内部的函数,只允许在类内调用,不想让类外的对象使用,所以设为了私有成员函数。
其实大部分的成员函数实现起来较简单,在此我就只挑出重要且易错的函数讨论一下。
(一)构造函数
一个类的构造函数很重要,要是构造函数没有写好,那后果不堪设想。
Date(int year, int month, int day) { if (year < 1900 || month>12 || month < 1 || day<1 || day>GetMonthDay(year, month)) { cout << "初始化错误,日期重置为:1900-1-1" << endl; _year = 1900; _month = 1; _day = 1; } else { _year = year; _month = month; _day = day; } }
设计一个程序要设计的让使用者使用起来良好,符合大众认知。国际的标准公历都是从1900-1-1开始计时的。所以初始化时要处理一下不能小于199-1-1.
(二)GetMonthDay()和IsLeapYear()
要使一个程序的可读性和健壮性提高,我们要尽可能少写重复的代码。我们把经常要调用的代码封装成一个函数,修改程序时也特别方便。
此日期类中GetMonthDay()和IsLeapYear()函数是一个经常调用函数,因为要得到一年的天数就必须先判断是平年还是闰年,然后得到每个月的天数,然后相加。所以这两个私有函数配合起来可以得到某一年的天数。
bool Date::IsLeapYear(int year) { if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) { return true; } else { return false; } } int Date::GetMonthDay(int year, int month) { int MonthArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int day = MonthArray[month]; if (month == 2 && IsLeapYear(year)) { day += 1; } return day; }
这里GetMonthDay()使用了一种简单的方法来确定某年某月的天数,就是利用一个数组来存每个月的天数,数组的下标就表示月份,所以数组大小为13,下表为0的不用,没有0月。。。。。然后就判断是平年还是闰年,如果是闰年只要把多的那一天加上就行了。
(三)>,<,>=,<= 都可以归为一类
只要实现了<其他三个都可以用<去实现。
bool Date::operator<(const Date& d) { if (this->_year>d._year) return false; else if (this->_year < d._year) return true; else { if (this->_month > d._month) return false; else if (this->_month < d._month) return true; else { if (this->_day > d._day||this->_day==d._day) return false; else return true; } } }
(四)+,-,+=,-=归为一类
实现+=和-=,+和-可以根据他们实现
Date& Date::operator+= (int day) { if (day<0) { return (*this -= (-day)); } else { this->_day += day; while (this->_day > GetMonthDay(this->_year, this->_month)) { this->_day -= GetMonthDay(this->_year, this->_month); if (this->_month < 12) { this->_month++; } else { this->_year++; this->_month %= 12; } } return *this; } } Date& Date::operator-= (int day) { if (day < 0) { return (*this += (-day)); } this->_day -= day; while (this->_day < 1) { this->_month --; if (this->_month < 1) { this->_year--; this->_month += 12; if (this->_year < 1) { exit(1); } } this->_day += GetMonthDay(this->_year, this->_month); } return *this; }
其实实现起来很简单的,希望朋友们可以自己去实现一个,提高编程技巧,注重细节。