当前位置:   article > 正文

C++日期类的实现_c++编写一个日期时间处理类

c++编写一个日期时间处理类

目录

1.日期类的定义:Date.h

2.成员函数的实现:Date.cpp

 2.1准确获取某年某月有多少天

2.2日期类构造函数

(补充)2.3日期类拷贝构造

2.4赋值运算符重载

2.5+=运算符重载

2.6+运算符重载

2.7-=运算符重载

 2.8-运算符重载

2.9前置++运算符重载

(补充)2.10前置--运算符重载

(补充)2.11后置-- 运算符重载

2.12后置++运算符重载

2.13>运算符重载

2.14==运算符重载

2.15>=运算符重载

2.16<运算符重载

2.17<=运算符重载

2.18!=运算符重载

2.19.计算两个日期之间的间隔天数,日期减去日期

 

3.测试:Test.h


1.日期类的定义:Date.h

  1. #pragma once
  2. #include <iostream>
  3. #include <assert.h>
  4. using std::cout;
  5. using std::cin;
  6. using std::endl;
  7. class Date
  8. {
  9. public:
  10. //获取某年某月的天数
  11. int GetMonthDay(int year, int month);
  12. //全缺省的构造函数
  13. Date(int year = 0, int month = 1, int day = 0);
  14. //打印
  15. void Print();
  16. //析构、拷贝构造,赋值重载可以不写,默认生成的就够用,像Stack才需要自己写
  17. //d+100
  18. //赋值运算符重载
  19. Date& operator+=(int day);
  20. Date operator+(int day);
  21. Date& operator-=(int day);
  22. Date operator-(int day);
  23. //返回两个日期之间相隔的具体天数
  24. int operator-(const Date& d);
  25. //++d -> d.operator++(&d)
  26. Date& operator++();
  27. //d++ -> d.operator++(&d,0)
  28. //int参数不需要给实参,因为没用,它的作用是为了和前置++构成函数重载
  29. Date operator++(int);
  30. //运算符重载
  31. bool operator>(const Date& d);
  32. bool operator<(const Date& d);
  33. bool operator>=(const Date& d);
  34. bool operator<=(const Date& d);
  35. bool operator==(const Date& d);
  36. bool operator!=(const Date& d);
  37. private:
  38. int _year;
  39. int _month;
  40. int _day;
  41. };

2.成员函数的实现:Date.cpp

 2.1准确获取某年某月有多少天

  1. inline int GetMonthDay(int year, int month)
  2. {
  3. //数组存储平年每个月的天数
  4. static int dayArray[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
  5. int i = dayArray[month];
  6. if (month == 2 && ((year%4==0&&year%100!=0)||(year%400 == 0)))
  7. {
  8. i = 29;
  9. }
  10. return i;
  11. }


2.2日期类构造函数

  1. Date::Date(int year, int month, int day)//缺省参数在声明和实现两边只有一边可用
  2. {
  3. //检查日期的合法性
  4. if (year>=0 &&month>0&&month<13 &&day>0&&day<=GetMonthDay(year,month))
  5. {
  6. _year = year;
  7. _month = month;
  8. _day = day;
  9. }
  10. else
  11. {
  12. //严格来说抛异常更好
  13. cout << "非法日期" << endl;
  14. cout << year << "年" << month << "月" << day << "日" << endl;
  15. }
  16. }


(补充)2.3日期类拷贝构造

  1. Date::Date(const Date& d)
  2. {
  3. _year = d._year;
  4. _month = d._month;
  5. _day = d._day;
  6. }


2.4赋值运算符重载

  1. Date& Date:: operator=(const Date& d)
  2. {
  3. _year = d._year;
  4. _month = d._month;
  5. _day = d._day;
  6. return *this; //这个可不能少,少了遇上连续赋值语句a=b=c会出错。
  7. }

 写拷贝构造和赋值时要加上const


2.5+=运算符重载

 

考虑越界情况

  • 如果_day加了整数以后,<=该月最大天数,则不需要修改,直接返回该日期.
  • 如果_day加了整数以后,>该月最大天数,则_day减去新的月所拥有的最大天数,然后该月加1
  • 如果执行了第二步后,_day仍大于新的月所拥有天数,继续执行第二步,并且循环
  1. //类似加法进位的规则:1.天满了,减去当前月的天数,月+1
  2. //2.月满了,年+1,月置成1
  3. Date& Date::operator+=(int day)
  4. {
  5. if (day < 0)
  6. {
  7. *this -= -day;
  8. }
  9. else
  10. {
  11. _day += day;
  12. //天数不合法,不断进位使其合法
  13. while (_day > GetMonthDay(_year, _month))
  14. {
  15. _day -= GetMonthDay(_year, _month);
  16. _month++;
  17. if (_month > 12)
  18. {
  19. ++_year;
  20. _month = 1;
  21. }
  22. }
  23. }
  24. return *this;
  25. }

或者用+=复用+

  1. Date& Date::operator+=(int day)
  2. {
  3. *this = *this +day;
  4. return *this;
  5. }

用+来复用+= 

  1. Date Date::operator+(int day)
  2. {
  3. Date ret(*this);
  4. ret += day;
  5. return ret;
  6. }

两种复用的比较:第一种调用+有两次拷贝构造,调用+=没有拷贝构造;第二种调用+和+=都有两次拷贝构造

 

2.6+运算符重载

  1. Date Date::operator+(int day)
  2. {
  3. Date ret(*this);
  4. //复用operator+=
  5. ret += day; //相当于ret.operator+=(day)
  6. return ret;
  7. }


2.7-=运算符重载

  1. Date& Date::operator-=(int day)
  2. {
  3. if(day<0)
  4. {
  5. //_day += -day;
  6. 天数不合法,不断进位使其合法
  7. //while (_day > GetMonthDay(_year, _month))
  8. //{
  9. // _day -= GetMonthDay(_year, _month);
  10. // _month++;
  11. // if (_month > 12)
  12. // {
  13. // ++_year;
  14. // _month = 1;
  15. // }
  16. //}
  17. //复用调用上面的函数
  18. * this += -day;
  19. }
  20. else
  21. {
  22. /*_day -= day;
  23. while (_day <= 0)
  24. {
  25. --_month;
  26. if (_month == 0)
  27. {
  28. --_year;
  29. _month = 12;
  30. }
  31. _day += GetMonthDay(_year, _month);
  32. }*/
  33. * this -= day;
  34. }
  35. return *this;
  36. }


 
2.8-运算符重载

  1. Date Date::operator-(int day)
  2. {
  3. Date tmp = *this;
  4. tmp -= day;//tmp.operator
  5. return tmp;
  6. }


2.9前置++运算符重载

  1. //++d -> d.operator++(&d)
  2. Date& Date::operator++()
  3. {
  4. *this += 1;
  5. return *this;
  6. }


(补充)2.10前置--运算符重载

  1. Date& Date::operator--()
  2. {
  3. *this -= 1;
  4. return *this;
  5. }


(补充)2.11后置-- 运算符重载

  1. Date& Date::operator--(int) //这个int用于区分前置还是后置
  2. {
  3. Date tmp(*this);
  4. *this -= 1;
  5. return tmp;
  6. }


2.12后置++运算符重载

  1. //d++ -> d.operator++(&d,0)
  2. //int参数不需要给实参,因为没用,它的作用是为了和前置++构成函数重载
  3. Date Date::operator++(int)
  4. {
  5. Date tmp(*this);
  6. *this += 1;
  7. return tmp;
  8. }


2.13>运算符重载

  1. bool Date::operator>(const Date& d)
  2. {
  3. if (_year > d._year)
  4. {
  5. return true;
  6. }
  7. else if(_year == d._year)
  8. {
  9. if (_month > d._month)
  10. {
  11. return true;
  12. }
  13. else if (_month == d._month)
  14. {
  15. if (_day > d._day)
  16. {
  17. return true;
  18. }
  19. }
  20. }
  21. return false;
  22. }


2.14==运算符重载

  1. bool Date::operator==(const Date& d)
  2. {
  3. return _year = d._year
  4. && _month == d._month
  5. && _day == d._day;
  6. }


2.15>=运算符重载

  1. bool Date::operator>=(const Date& d)
  2. {
  3. return *this > d || *this == d;
  4. }


2.16<运算符重载

  1. bool Date::operator<(const Date& d)
  2. {
  3. return !(*this >= d);
  4. }


2.17<=运算符重载

  1. bool Date::operator<(const Date& d)
  2. {
  3. return !(*this >= d);
  4. }


2.18!=运算符重载

  1. bool Date::operator!=(const Date& d)
  2. {
  3. return !(*this == d);
  4. }


2.19.计算两个日期之间的间隔天数,日期减去日期

  1. //调用前面实现的各种函数来实现
  2. int Date::operator-(const Date& d)
  3. {
  4. //效率差别不大的情况下,尽量选择可读性强的,简单的程序
  5. Date max = *this;
  6. Date min = d;
  7. int flag = 1;
  8. if (*this<d)
  9. {
  10. max = d;
  11. min = *this;
  12. flag = -1;
  13. }
  14. int n = 0;
  15. while (min != max)
  16. {
  17. ++min;
  18. ++n;
  19. }
  20. return n * flag;
  21. }


 

3.测试:Test.h

  1. #include "Date.h"
  2. void Test1()
  3. {
  4. Date d1(2021, 5, 25);
  5. d1.Print();
  6. Date d2(2021, 0, 0);
  7. //d2.Print();
  8. Date d3(2021, 2, 29);
  9. d3.Print();
  10. }
  11. void Test2()
  12. {
  13. Date d1(2021, 5, 25);
  14. d1.Print();
  15. d1 += 3;
  16. d1.Print();
  17. d1 += 17;
  18. d1.Print();
  19. }
  20. void Test3()
  21. {
  22. Date d1(2021, 5, 27);
  23. d1 -= 120;
  24. d1.Print();
  25. Date d2(2021, 5, 27);
  26. d2 -= -100;
  27. d2.Print();
  28. Date d3(2021, 5, 27);
  29. d3 += 100;
  30. d3.Print();
  31. Date d4(2021, 5, 27);
  32. d4 += -100;
  33. d4.Print();
  34. }
  35. void Test4()
  36. {
  37. Date d1(2021, 5, 27);
  38. //前置++和后置++都完成了++,不同的地方在于返回值不一样
  39. //因为他们的运算符是一样的,函数名就是一样的,
  40. //为了区分,对后置++做了特殊处理,加了一个参数,形成函数重载
  41. Date ret1 = d1++;//d1.operator++(&d1)
  42. ret1.Print();
  43. d1.Print();
  44. Date ret2 = ++d1;//d1.operator++(&d1,0)
  45. ret2.Print();
  46. d1.Print();
  47. }
  48. void Test5()
  49. {
  50. Date d1(2021, 5, 27);
  51. Date d2(2021, 12, 31);
  52. cout << d2 - d1 << endl;
  53. cout << d1 - d2 << endl;
  54. }
  55. int main()
  56. {
  57. Test5();
  58. return 0;
  59. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/127527
推荐阅读
相关标签
  

闽ICP备14008679号