自定义一个Date对象,主要实现在对日期的相应处理。
实现的功能:
- 日期合法性的判断
- 日期比较大小
- 计算两个日期之差
- 日期加上指定年份
- 日期加上指定月份
- 日期加上指定天数
- 日期转字符串
C++完整代码
#include <iostream>
#include <ctime>
#include<cstdlib>
#include <sstream>
#include<climits>
using namespace std;
class Date {
private:
int year,month,day;
int buff[13];
//以2000.1.1为基准计算与 y.m.d 相差天数
int currDateToOriginalDays(int y,int m,int d) {
int total = 0;
int flag = 1;
int a = 2000; //原始日期 2001.1.1
int b = y;
if(y<2000) {
flag = -1;
a = y;
b = 2000;
}
while(a<b) {
total += 365;
total += isLeap(a);
a++;
}
for(int i = 1; i<m; i++) {
total += buff[i];
}
if(m>2) {
total+=isLeap(y);
}
total += d;
return total*flag;
}
public:
Date(int yy,int mm,int dd):year(yy),month(mm),day(dd) {
int temp[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
for (int i = 0; i < sizeof(temp) / sizeof(int); i++) {
buff[i] = temp[i];
}
}
int isLeap(int yy) {
return ((yy%4==0 && yy%100!=0)||(yy%400==0))?1:0;
}
Date(Date &p) {
year = p.year;
month = p.month;
day = p.day;
}
//判断日期是否合法
bool isEffectful() {
if(year>0 && month>=1 && month<=12 && day>0 && day<=31) {
int monthdays = buff[month];
if(month==2) {
monthdays+=isLeap(year);
}
// 得出正确的日期,那么就好排除其他日期为错误日期
if(day<=buff[month]) {
return 1;
}
}
return 0;
}
int getYear() const {
return year;
}
int getMonth() const {
return month;
}
int getDay() const {
return day;
}
// 转为日期格式字符串
string toString() {
char ch[11];
sprintf(ch,"%d-%d-%d",year,month,day);
// 新编译器则需替换为以下
// sprintf_s(ch,sizeof(ch),"%d-%d-%d", year, month, day);
string str = ch;
return str;
}
friend ostream& operator<<(ostream &os,Date &date) {
os<<date.year<<"-"<<date.month<<"-"<<date.day;
return os;
}
friend int operator<(Date &p1,Date &p2) {
return (p1-p2<0)?1:0;
}
friend int operator!=(Date &p1,Date &p2) {
if(p1.year==p2.year && p1.month==p2.month && p1.day==p2.month) {
return 0;
}
return 1;
}
//日期相减
friend int operator-(Date &p1,Date &p2) {
if(!p1.isEffectful()||!p2.isEffectful()) {
cout<<"日期错误!"<<endl;
exit(0);
}
int sum1 = p1.currDateToOriginalDays(p1.year,p1.month,p1.day);
int sum2 = p2.currDateToOriginalDays(p2.year,p2.month,p2.day);
return sum1 - sum2;
}
//当前日期加上几个月
friend void addMonths(Date &date,int mm) {
if(mm<0) {
cout<<"参数不能小于 0 !"<<endl;
return ;
// exit(0);
}
int newyear = date.year+(date.month+mm)/12;
int newmonth = (date.month+mm)%12;
newmonth = (newmonth==0)?12:newmonth;
if(newmonth>12) {
newyear++;
newmonth = newmonth - 12;
}
if(date.day>27) {
int monthDays = date.getMonthDays(newyear,newmonth);
if(date.day>monthDays) {
date.day = monthDays;
}
}
date.year = newyear;
date.month = newmonth;
}
//获取指定月份的天数
int getMonthDays(int yy,int mm) {
if(mm==2) {
return buff[mm]+isLeap(yy);
} else {
return buff[mm];
}
}
//当前日期加上指定天数 ( 大于 0 )
friend void addDays(Date &date,int extra) {
while(true) {
//每个月份天数
int currdays = date.getMonthDays(date.year,date.month);
if(extra+date.day>currdays) {
//每次循环添加的天数
int surplus = currdays-date.day+1; // 不加 1 则 结果少 1
date.month++;
date.day = 1;
//添加的天数
if(date.month==13) {
date.year++;
date.month = 1;
}
// extra 剩余待添加的天数
extra = extra - surplus;
} else {
date.day+=extra;
break;
}
}
// cout<<"extra:"<<extra<<endl;
}
//添加指定年份
friend void addYears(Date &date,int yy) {
int newyear = date.year+yy;
// 闰年 2 月转到平年 2 月
if(date.isLeap(date.year) && date.month==2 && date.day==29) {
date.day = (date.isLeap(newyear)?29:28);
}
date.year = newyear;
}
};
// 获取当前系统日期工具函数
string getDate() {
// 基于当前系统的当前日期/时间
time_t now = time(0);
tm *ltm = localtime(&now);
// 输出 tm 结构的各个组成部分
int year = 1900 + ltm->tm_year;
int month = 1+ltm->tm_mon;
int day = ltm->tm_mday;
char ch[11];
sprintf(ch,"%d-%d-%d",year,month,day);
// 字符数组赋值给字符串
string str = ch;
return str;
}
// 测试函数
void Date_test() {
srand(time(0));
cout<<"自定义日期对象测试"<<endl;
cout<<"1.随机产生日期校验是否合法"<<endl;
int count = 10;
while(count--) {
int y,m,d;
y =2000+rand()%5;
m =1+rand()%10;
d =29+rand()%4;
Date p(y,m,d);
cout<<y<<"-"<<m<<"-"<<d<<"\t";
// 如果日期合法
if(p.isEffectful()) {
cout<<"正确!"<<endl;
} else {
cout<<"错误!"<<endl;
}
cout<<endl;
}
cout<<"2.日期加上指定年数、月数、天数"<<endl;
count = 10;
while(count--) {
int y,m,d;
y =1993+rand()%20;
m =1+rand()%10;
d =29+rand()%4;
Date q(y,m,d);
if(!q.isEffectful()) {
continue;
}
int x = rand()%11;
cout<<q<<"\t加上指定年数:"<<x;
addYears(q,x);
cout<<"\t结果:"<<q<<endl;
cout<<q<<"\t加上指定月数:"<<x;
addMonths(q,x);
cout<<"\t结果:"<<q<<endl;
cout<<q<<"\t加上指定天数:"<<x;
addDays(q,x);
cout<<"\t结果:"<<q<<endl;
cout<<endl;
}
Date R(2019,1,1);
cout<<"3.日期转为字符串:";
cout<<R.toString()<<endl;
cout<<endl;
cout<<"当前日期:"<<getDate()<<endl;
}
int main() {
Date_test();
}