zoukankan      html  css  js  c++  java
  • C++实现Date日期类

    定义一个Date类,包含三个属性年、月、日

    实现了如下功能:

    1. 年月日的增加、减少:2017年10月1日加上100个月30天是2025年5月31日
    2. 输出某天是星期几:2017年10月1日是星期日
    3. 判断某一年是否是闰年:2020年是闰年
    4. 下一个工作日(周末)日期:2010年10月2日下一个周末是10月8日
     1 class Date
     2 {
     3   public:
     4     Date();
     5     Date(int yy, Month mm, int dd);
     6     int day() const { return m_day; }
     7     int year() const { return m_year; }
     8     Month month() const { return m_month; }
     9 
    10     void add_day(int dd);//增加或减少天数
    11     void add_month(int mm);//增加或减少月份
    12     void add_year(int yy);//增加或减少年份
    13 
    14   private:
    15     int m_year;
    16     Month m_month;
    17     int m_day;
    18 };
    19 //判断日期是否合法
    20 bool is_date(int y, Month m, int d);
    21 //判断是否为闰年
    22 bool leapyear(int y);
    23 //两个Date是否相等
    24 bool operator==(const Date &a, const Date &b);
    25 bool operator!=(const Date &a, const Date &b);
    26 //Date输入输出
    27 ostream &operator<<(ostream &os, const Date &d);
    28 istream &operator>>(istream &is, Date &dd);
    29 //今天是星期几
    30 Day day_of_week(const Date &date);
    31 ostream &operator<<(ostream &os, const Day &d);
    32 //下一个周末
    33 Date next_Sunday(const Date &d);
    34 //下一个工作日
    35 Date next_weekday(const Date &d);

    具体的实现代码如下:

      1 #include <iostream>
      2 #include <vector>
      3 #include <string>
      4 
      5 using std::istream;
      6 using std::ostream;
      7 using std::vector;
      8 using std::ios_base;
      9 using std::string;
     10 
     11 namespace Chrono
     12 {
     13 class InvalidDate
     14 {
     15   public:
     16     std::string what() { return "InValid Date Occured"; };
     17 };
     18 
     19 enum class Month
     20 {
     21     jan = 1, //January
     22     feb,     //February
     23     mar,     //March
     24     apr,     //April
     25     may,     //May
     26     jun,     //June
     27     jul,     //July
     28     aug,     //August
     29     sep,     //September
     30     oct,     //October
     31     nov,     //November
     32     dec      //December
     33 };
     34 
     35 enum class Day
     36 {
     37     sun, //sunday
     38     mon, //monday
     39     tue, //tuesday
     40     wed, //wednesday
     41     thu, // thursday
     42     fri, //friday
     43     sat  //saturday
     44 };
     45 
     46 class Date
     47 {
     48   public:
     49     Date();
     50     Date(int yy, Month mm, int dd);
     51     int day() const { return m_day; }
     52     int year() const { return m_year; }
     53     Month month() const { return m_month; }
     54 
     55     void add_day(int dd);
     56     void add_month(int mm);
     57     void add_year(int yy);
     58 
     59   private:
     60     int m_year;
     61     Month m_month;
     62     int m_day;
     63 };
     64 
     65 bool is_date(int y, Month m, int d);
     66 bool leapyear(int y);
     67 bool operator==(const Date &a, const Date &b);
     68 bool operator!=(const Date &a, const Date &b);
     69 ostream &operator<<(ostream &os, const Date &d);
     70 istream &operator>>(istream &is, Date &dd);
     71 Day day_of_week(const Date &date);
     72 ostream &operator<<(ostream &os, const Day &d);
     73 
     74 Date next_Sunday(const Date &d);
     75 Date next_weekday(const Date &d);
     76 
     77 ////////////////////////////////////////////////////////////////////////////////
     78 //Implements                                                               /////
     79 ////////////////////////////////////////////////////////////////////////////////
     80 Date::Date(int yy, Month mm, int dd) : m_year(yy), m_month(mm), m_day(dd)
     81 {
     82     if (!is_date(yy, mm, dd))
     83         throw InvalidDate{};
     84 }
     85 
     86 const Date &default_date()
     87 {
     88     static const Date d{2001, Month::jan, 1};
     89     return d;
     90 }
     91 
     92 Date::Date() : m_year(default_date().year()),
     93                m_month(default_date().month()),
     94                m_day(default_date().day()) {}
     95 
     96 void Date::add_day(int dd)
     97 {
     98     if (dd > 0)
     99     {
    100         for (; dd > 0; --dd)
    101         {
    102             int temp_d = m_day + 1;
    103             switch (month())
    104             {
    105             case Month::feb:
    106                 if ((leapyear(m_year) && temp_d > 29) || (!leapyear(m_year) && temp_d > 28))
    107                 {
    108                     temp_d = 1;
    109                     m_month = Month::mar;
    110                 }
    111                 break;
    112             case Month::apr:
    113             case Month::jun:
    114             case Month::sep:
    115             case Month::nov:
    116                 if (temp_d > 30)
    117                 {
    118                     temp_d = 1;
    119                     m_month = Month((int)m_month + 1);
    120                 }
    121                 break;
    122             case Month::dec:
    123                 if (temp_d > 31)
    124                 {
    125                     temp_d = 1;
    126                     m_month = Month::jan;
    127                     m_year += 1;
    128                 }
    129                 break;
    130             default:
    131                 if (temp_d > 31)
    132                 {
    133                     temp_d = 1;
    134                     m_month = Month((int)m_month + 1);
    135                 }
    136                 break;
    137             }
    138             m_day = temp_d;
    139         }
    140     }
    141     else if (dd < 0)
    142     {
    143         for (; dd < 0; ++dd)
    144         {
    145             int temp_d = day() - 1;
    146             if (temp_d <= 0)
    147             {
    148                 switch (month())
    149                 {
    150                 case Month::jan:
    151                     m_month = Month::dec;
    152                     temp_d = 31;
    153                     m_year -= 1;
    154                     break;
    155                 case Month::mar:
    156                     m_month = Month::feb;
    157                     if (leapyear(m_year))
    158                         temp_d = 29;
    159                     else
    160                         temp_d = 28;
    161                     break;
    162                 case Month::feb:
    163                 case Month::apr:
    164                 case Month::jun:
    165                 case Month::oct:
    166                 case Month::sep:
    167                 case Month::nov:
    168                     temp_d = 31;
    169                     m_month = Month((int)m_month - 1);
    170                     break;
    171                 default:
    172                     temp_d = 30;
    173                     m_month = Month((int)m_month - 1);
    174                     break;
    175                 }
    176             }
    177             m_day = temp_d;
    178         }
    179     }
    180 }
    181 
    182 void Date::add_month(int month)
    183 {
    184     int temp_y = month / 12 + m_year;
    185     int temp_m = month % 12 + (int)m_day;
    186 
    187     if (temp_y <= 0)
    188     {
    189         temp_y--;
    190         temp_m = temp_m + 12;
    191     }
    192     else if (temp_m > 12)
    193     {
    194         temp_y++;
    195         temp_m = temp_m - 12;
    196     }
    197     m_year = temp_y;
    198     m_month = Month(temp_m);
    199     switch (m_month)
    200     {
    201     case Month::feb:
    202         if (leapyear(m_year) && m_day > 29)
    203             m_day = 29;
    204         else if (!leapyear(m_year) && m_day > 28)
    205             m_day = 28;
    206         break;
    207     case Month::apr:
    208     case Month::jun:
    209     case Month::sep:
    210     case Month::nov:
    211         if (m_day > 30)
    212             m_day = 30;
    213     default:
    214         break;
    215     }
    216 }
    217 
    218 void Date::add_year(int n)
    219 {
    220     if (month() == Month::feb && day() == 29 && !leapyear(m_year + n))
    221         m_day = 28;
    222     m_year += n;
    223 }
    224 
    225 bool is_date(int y, Month m, int d)
    226 {
    227     if (d <= 0)
    228         return false;
    229     if (m < Month::jan || m > Month::dec)
    230         return false;
    231     int days_in_month;
    232     switch (m)
    233     {
    234     case Month::feb:
    235         days_in_month = leapyear(y) ? 29 : 28;
    236         break;
    237     case Month::apr:
    238     case Month::jun:
    239     case Month::sep:
    240     case Month::nov:
    241         days_in_month = 30;
    242         break;
    243     default:
    244         days_in_month = 31;
    245         break;
    246     }
    247     if (days_in_month < d)
    248         return false;
    249     return true;
    250 }
    251 
    252 // https://en.wikipedia.org/wiki/Leap_year#Algorithm
    253 bool leapyear(int y)
    254 {
    255     if (y % 4 != 0)
    256         return false;
    257     else if (y % 100 != 0)
    258         return true;
    259     else if (y % 400 != 0)
    260         return false;
    261     return true;
    262 }
    263 bool operator==(const Date &a, const Date &b)
    264 {
    265     return a.year() == b.year() && a.month() == b.month() && a.day() == b.day();
    266 }
    267 
    268 bool operator!=(const Date &a, const Date &b)
    269 {
    270     return !(a == b);
    271 }
    272 
    273 ostream &operator<<(ostream &os, const Date &d)
    274 {
    275     return os << '(' << d.year()
    276               << ',' << (int)d.month()
    277               << ',' << d.day() << ')';
    278 }
    279 
    280 ostream &operator<<(ostream &os, const Day &d)
    281 {
    282     vector<string> weekdays{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
    283     os << weekdays[(int)d];
    284     return os;
    285 }
    286 
    287 // format (2017,5,23)
    288 istream &operator>>(istream &is, Date &d)
    289 {
    290     int yy, mm, dd;
    291     char ch1, ch2, ch3, ch4;
    292     is >> ch1 >> yy >> ch2 >> mm >> ch3 >> dd >> ch4;
    293     if (!is)
    294         return is;
    295     if (ch1 != '(' || ch2 != ',' || ch3 != ',' || ch4 != ')')
    296         is.clear(ios_base::failbit);
    297     d = Date{yy, Month(mm), dd};
    298     return is;
    299 }
    300 
    301 // https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html
    302 Day day_of_week(const Date &date)
    303 {
    304     int y = date.year();
    305     int m = (int)date.month();
    306     int d = date.day();
    307     y -= m < 3;
    308     int day_of_week = (y + y / 4 - y / 100 + y / 400 + "-bed=pen+mad."[m] + d) % 7;
    309     return Day(day_of_week);
    310 }
    311 Date next_Sunday(const Date &d)
    312 {
    313     Date d1 = d;
    314     while (day_of_week(d1) != Day::sun)
    315     {
    316         d1.add_day(1);
    317     }
    318     return d1;
    319 }
    320 
    321 Date next_weekday(const Date &d)
    322 {
    323     Date d1 = d;
    324     if (day_of_week(d1) == Day::sat)
    325         d1.add_day(2);
    326     else if (day_of_week(d1) == Day::fri)
    327         d1.add_day(3);
    328     else
    329         d1.add_day(1);
    330     return d1;
    331 }
    332 }
    代码实现
  • 相关阅读:
    原生态ajax
    用js提交表单,没有submit按钮如何验证,使用button提交方法
    易买网吐血文档(图片拖不上来,要文档留下联系)
    时序图Sequence DiaGram
    starUML用例图
    泛型自动扩容的原理
    深入C#数据类型
    了解.NET框架
    自定义jstl标签实现页面级的权限控制
    SharePoint 2013 REST 服务使用简介
  • 原文地址:https://www.cnblogs.com/lkpp/p/chrono-date.html
Copyright © 2011-2022 走看看