paranid5

Date and Time

Jun 16th, 2020
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.17 KB | None | 0 0
  1. //Time.h
  2.  
  3. #ifndef TIME_H
  4. #define TIME_H
  5. #define LL long long
  6. class Time
  7. {
  8. public:
  9.     virtual ~Time() = default;
  10.  
  11.     Time(LL, LL, LL);
  12.  
  13.     void set_hours(LL);
  14.  
  15.     void set_min(LL);
  16.  
  17.     void set_sec(LL);
  18.  
  19.     LL get_hours() const;
  20.  
  21.     LL get_min() const;
  22.  
  23.     LL get_sec() const;
  24.  
  25.     void change_sec(LL);
  26.  
  27. protected:
  28.     virtual void change_day(LL);
  29.  
  30. private:
  31.     LL hour_;
  32.     LL min_;
  33.     LL sec_;
  34. };
  35.  
  36. #endif // TIME_H
  37.  
  38.  
  39.  
  40. //Time.cpp
  41.  
  42. #include "Time.h"
  43.  
  44. Time::Time(const LL hour, const LL min, const LL sec)
  45. {
  46.     hour_ = hour;
  47.     min_ = min;
  48.     sec_ = sec;
  49. }
  50.  
  51. void Time::set_hours(const LL hour)
  52. {
  53.     if (hour < 24 && hour > -1)
  54.         hour_ = hour;
  55. }
  56.  
  57. void Time::set_min(const LL min)
  58. {
  59.     if (min < 60 && min > -1)
  60.         min_ = min;
  61. }
  62.  
  63. void Time::set_sec(const LL sec)
  64. {
  65.     if (sec < 60 && sec > -1)
  66.         sec_ = sec;
  67. }
  68.  
  69. LL Time::get_hours() const
  70. {
  71.     const LL hours = hour_;
  72.     return hours;
  73. }
  74.  
  75. LL Time::get_min() const
  76. {
  77.     const LL min = min_;
  78.     return min;
  79. }
  80.  
  81. LL Time::get_sec() const
  82. {
  83.     const LL sec = sec_;
  84.     return sec;
  85. }
  86.  
  87. void Time::change_day(LL)
  88. {
  89.    
  90. }
  91.  
  92. void Time::change_sec(const LL change)
  93. {
  94.     LL t = hour_ * 3600 + min_ * 60 + sec_;
  95.     t += change;
  96.     sec_ = (t % 60 + 60) % 60;
  97.     min_ = ((t / 60) % 60 + 60) % 60;
  98.     hour_ = ((t / 3600) % 24 + 24) % 24;
  99.     const LL days = (t + change) / 60 / 60 / 24;
  100.     change_day(days);
  101. }
  102.  
  103.  
  104.  
  105.  
  106. //Date.h
  107.  
  108. #ifndef DATE_H
  109. #define DATE_H
  110. #include "Time.h"
  111.  
  112. class Date : public Time
  113. {
  114. public:
  115.     Date(LL, LL, LL, LL, LL, LL);
  116.  
  117.     void set_date(LL, LL, LL);
  118.  
  119.     LL get_year() const;
  120.  
  121.     LL get_month() const;
  122.  
  123.     LL get_day() const;
  124.  
  125.     static bool leap(LL);
  126.  
  127.     void shift_day(LL);
  128.  
  129. protected:
  130.     void change_day(const LL d) override { shift_day(d); }
  131.  
  132. private:
  133.     LL day_;
  134.     LL month_;
  135.     LL year_;
  136.     LL collect_day() const;
  137. };
  138.  
  139. #endif // DATE_H
  140.  
  141.  
  142.  
  143.  
  144. //Date.cpp
  145.  
  146. #include "Date.h"
  147. #include <stdexcept>
  148. #define OST(X, Y) (((X) % (Y) + (Y)) % (Y))
  149. #define ABS(X) ((X) > 0) ? (X) : (-(X))
  150. #define SWAP(X, Y, T) T SWAP = X; (X) = Y; (Y) = SWAP;
  151.  
  152. Date::Date(const LL year, const LL month_th, const LL day, const LL hour, const LL min, const LL sec) : Time(hour, min, sec)
  153. {
  154.     year_ = year;
  155.     month_ = month_th;
  156.     day_ = day;
  157. }
  158.  
  159. bool Date::leap(const LL year)
  160. {
  161.     return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
  162. }
  163.  
  164. void Date::set_date(const LL year, const LL month_th, const LL day)
  165. {
  166.     if (year != 0) year_ = year;
  167.     else
  168.     {
  169.         throw std::invalid_argument("Incorrect year");
  170.         return;
  171.     }
  172.     if (month_th > 0 && month_th < 13) month_ = month_th;
  173.     else
  174.     {
  175.         throw std::invalid_argument("Incorrect month");
  176.         return;
  177.     }
  178.     if (day > 0)
  179.     {
  180.         switch (month_th)
  181.         {
  182.         case 1: // январь
  183.             if (day < 32) day_ = day;
  184.             else throw std::invalid_argument("Incorrect day");
  185.             return;
  186.         case 2: // февраль
  187.             if (day < 30)
  188.             {
  189.                 if (leap(year)) day_ = day;
  190.                 else if (day < 29) day_ = day;
  191.                 else throw std::invalid_argument("Incorrect day. Selected year is not leap");
  192.             }
  193.             else throw std::invalid_argument("Incorrect day");
  194.             return;
  195.         case 3: // март
  196.             if (day < 32) day_ = day;
  197.             else throw std::invalid_argument("Incorrect day");
  198.             return;
  199.         case 4: // апрель
  200.             if (day < 31) day_ = day;
  201.             else throw std::invalid_argument("Incorrect day");
  202.             return;
  203.         case 5: // май
  204.             if (day < 32) day_ = day;
  205.             else throw std::invalid_argument("Incorrect day");
  206.             return;
  207.         case 6: // июнь
  208.             if (day < 31) day_ = day;
  209.             else throw std::invalid_argument("Incorrect day");
  210.             return;
  211.         case 7: // июль
  212.             if (day < 32) day_ = day;
  213.             else throw std::invalid_argument("Incorrect day");
  214.             return;
  215.         case 8: // август
  216.             if (day < 32) day_ = day;
  217.             else throw std::invalid_argument("Incorrect day");
  218.             return;
  219.         case 9: // сентябрь
  220.             if (day < 31) day_ = day;
  221.             else throw std::invalid_argument("Incorrect day");
  222.             return;
  223.         case 10: // октябрь
  224.             if (day < 32) day_ = day;
  225.             else throw std::invalid_argument("Incorrect day");
  226.             return;
  227.         case 11: // ноябрь
  228.             if (day < 31) day_ = day;
  229.             else throw std::invalid_argument("Incorrect day");
  230.             return;
  231.         default: // декабрь
  232.             if (day < 32) day_ = day;
  233.             else throw std::invalid_argument("Incorrect day");
  234.             return;
  235.         }
  236.     }
  237.     else
  238.     {
  239.         throw std::invalid_argument("Incorrect day");
  240.         return;
  241.     }
  242. }
  243.  
  244. LL Date::get_year() const
  245. {
  246.     const LL year = year_;
  247.     return year;
  248. }
  249.  
  250. LL Date::get_month() const
  251. {
  252.     const LL month_th = month_;
  253.     return month_th;
  254. }
  255.  
  256. LL Date::get_day() const
  257. {
  258.     const LL day = day_;
  259.     return day;
  260. }
  261.  
  262. LL Date::collect_day() const
  263. {
  264.     LL collect = 0; // текущее кол-во дней относительно 0
  265.     if (year_ < 0)
  266.     {
  267.         collect--; // анти 0 день
  268.         LL y = -1; // считаем год
  269.         while (y > year_)
  270.         {
  271.             collect -= leap(y) ? 366 : 365;
  272.             y--;
  273.         }
  274.         switch (month_)
  275.         { // месяца идут наоборот
  276.         case 12: collect -= (31 - day_); break;
  277.         case 11: collect -= 31 + (30 - day_); break;
  278.         case 10: collect -= 31 + 30 + (31 - day_); break;
  279.         case 9:  collect -= 31 + 30 + 31 + (30 - day_); break;
  280.         case 8:  collect -= 31 + 30 + 31 + 30 + (31 - day_); break;
  281.         case 7:  collect -= 31 + 30 + 31 + 30 + 31 + (31 - day_); break;
  282.         case 6:  collect -= 31 + 30 + 31 + 30 + 31 + 30 + (30 - day_); break;
  283.         case 5:  collect -= 31 + 30 + 31 + 30 + 31 + 30 + 31 + (31 - day_); break;
  284.         case 4:  collect -= 31 + 30 + 31 + 30 + 31 + 30 + 31 + 31 + (30 - day_); break;
  285.         case 3:  collect -= 31 + 30 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + (31 - day_); break;
  286.         case 2:  collect -= 31 + 30 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + (29 - day_); break;
  287.         default: collect -= 31 + 30 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 29 + (31 - day_); break;
  288.         }
  289.         if (!leap(y) && month_ < 4) collect++;
  290.     }
  291.     else // year_ > 0
  292.     {
  293.         collect += day_; // прибавляя день, мы автоматом определяем знак (т.е. нет нужды collect++)
  294.         LL y = 1; // считаем год
  295.         while (y < year_)
  296.         {
  297.             collect += leap(y) ? 366 : 365;
  298.             y++;
  299.         }
  300.         switch (month_)
  301.         { // а здесь норм
  302.         case 1:  break;
  303.         case 2:  collect += 31; break;
  304.         case 3:  collect += 31 + 29; break;
  305.         case 4:  collect += 31 + 29 + 31; break;
  306.         case 5:  collect += 31 + 29 + 31 + 30; break;
  307.         case 6:  collect += 31 + 29 + 31 + 30 + 31; break;
  308.         case 7:  collect += 31 + 29 + 31 + 30 + 31 + 30; break;
  309.         case 8:  collect += 31 + 29 + 31 + 30 + 31 + 30 + 31; break;
  310.         case 9:  collect += 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31; break;
  311.         case 10: collect += 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30; break;
  312.         case 11: collect += 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; break;
  313.         default: collect += 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30; break;
  314.         }
  315.         if (!leap(y) && month_ > 2) collect--;
  316.     }
  317.     return collect;
  318. }
  319.  
  320. void Date::shift_day(const LL change)
  321. {
  322.     if (change == 0) return;
  323.     LL collect = collect_day();
  324.     const LL save = collect;
  325.     collect += change; // изменили кол-во дней
  326.     if (save > 0 && collect <= 0) collect--;
  327.     else if (save < 0 && collect >= 0) collect++; // вычёркивание 0 дня
  328.     if (collect < 0)
  329.     {
  330.         year_ = -1;
  331.         while (ABS(collect) >= 366)
  332.         {
  333.             if (ABS(collect) == 366) break;
  334.             collect += leap(year_) ? 366 : 365;
  335.             year_--;
  336.         }
  337.         if (ABS(collect) == 366 && !leap(year_))
  338.         {
  339.             collect += 365;
  340.             year_--;
  341.         }
  342.         if (ABS(collect) <= 31)
  343.         {
  344.             month_ = 12;
  345.             day_ = 31 - (ABS(collect));
  346.         }
  347.         else if (ABS(collect) <= 31 + 30)
  348.         {
  349.             month_ = 11;
  350.             collect += 31;
  351.             day_ = 30 - (ABS(collect));
  352.         }
  353.         else if (ABS(collect) <= 31 + 30 + 31)
  354.         {
  355.             month_ = 10;
  356.             collect += 31 + 30;
  357.             day_ = 31 - (ABS(collect));
  358.         }
  359.         else if (ABS(collect) <= 31 + 30 + 31 + 30)
  360.         {
  361.             month_ = 9;
  362.             collect += 31 + 30 + 31;
  363.             day_ = 30 - (ABS(collect));
  364.         }
  365.         else if (ABS(collect) <= 31 + 30 + 31 + 30 + 31)
  366.         {
  367.             month_ = 8;
  368.             collect += 31 + 30 + 31 + 30;
  369.             day_ = 31 - (ABS(collect));
  370.         }
  371.         else if (ABS(collect) <= 31 + 30 + 31 + 30 + 31 + 31)
  372.         {
  373.             month_ = 7;
  374.             collect += 31 + 30 + 31 + 30 + 31;
  375.             day_ = 31 - (ABS(collect));
  376.         }
  377.         else if (ABS(collect) <= 31 + 30 + 31 + 30 + 31 + 31 + 30)
  378.         {
  379.             month_ = 6;
  380.             collect += 31 + 30 + 31 + 30 + 31 + 31;
  381.             day_ = 30 - (ABS(collect));
  382.         }
  383.         else if (ABS(collect) <= 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31)
  384.         {
  385.             month_ = 5;
  386.             collect += 31 + 30 + 31 + 30 + 31 + 31 + 30;
  387.             day_ = 31 - (ABS(collect));
  388.         }
  389.         else if (ABS(collect) <= 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30)
  390.         {
  391.             month_ = 4;
  392.             collect += 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
  393.             day_ = 30 - (ABS(collect));
  394.         }
  395.         else if (ABS(collect) <= 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31)
  396.         {
  397.             month_ = 3;
  398.             collect += 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30;
  399.             day_ = 31 - (ABS(collect));
  400.         }
  401.         else
  402.         {
  403.             if (leap(year_))
  404.             {
  405.                 if (ABS(collect) <= 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 29)
  406.                 {
  407.                     month_ = 2;
  408.                     collect += 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31;
  409.                     day_ = 29 - (ABS(collect));
  410.                 }
  411.                 else
  412.                 {
  413.                     month_ = 1;
  414.                     collect += 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 29;
  415.                     day_ = 31 - (ABS(collect));
  416.                 }
  417.             }
  418.             else
  419.             {
  420.                 if (ABS(collect) <= 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28)
  421.                 {
  422.                     month_ = 2;
  423.                     collect += 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31;
  424.                     day_ = 28 - (ABS(collect));
  425.                 }
  426.                 else
  427.                 {
  428.                     month_ = 1;
  429.                     collect += 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28;
  430.                     day_ = 31 - (ABS(collect));
  431.                 }
  432.             }
  433.         }
  434.         day_++; // считаем от 0 дня
  435.         return;
  436.     }
  437.     else //collect > 0
  438.     {
  439.         year_ = 1;
  440.         while (collect >= 366)
  441.         {
  442.             if (collect == 366) break;
  443.             collect -= leap(year_) ? 366 : 365;
  444.             year_++;
  445.         }
  446.         if(collect == 366 && !leap(year_))
  447.         {
  448.             collect -= 365;
  449.             year_++;
  450.         }
  451.         if (collect <= 31) { month_ = 1; }
  452.         else
  453.         {
  454.             if (leap(year_))
  455.             {
  456.                 if (collect <= 31 + 29)
  457.                 {
  458.                     month_ = 2;
  459.                     collect -= 31;
  460.                 }
  461.                 else if (collect <= 31 + 29 + 31)
  462.                 {
  463.                     month_ = 3;
  464.                     collect -= 31 + 29;
  465.                 }
  466.                 else if (collect <= 31 + 29 + 31 + 30)
  467.                 {
  468.                     month_ = 4;
  469.                     collect -= 31 + 29 + 31;
  470.                 }
  471.                 else if (collect <= 31 + 29 + 31 + 30 + 31)
  472.                 {
  473.                     month_ = 5;
  474.                     collect -= 31 + 29 + 31 + 30;
  475.                 }
  476.                 else if (collect <= 31 + 29 + 31 + 30 + 31 + 30)
  477.                 {
  478.                     month_ = 6;
  479.                     collect -= 31 + 29 + 31 + 30 + 31;
  480.                 }
  481.                 else if (collect <= 31 + 29 + 31 + 30 + 31 + 30 + 31)
  482.                 {
  483.                     month_ = 7;
  484.                     collect -= 31 + 29 + 31 + 30 + 31 + 30;
  485.                 }
  486.                 else if (collect <= 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31)
  487.                 {
  488.                     month_ = 8;
  489.                     collect -= 31 + 29 + 31 + 30 + 31 + 30 + 31;
  490.                 }
  491.                 else if (collect <= 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30)
  492.                 {
  493.                     month_ = 9;
  494.                     collect -= 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31;
  495.                 }
  496.                 else if (collect <= 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31)
  497.                 {
  498.                     month_ = 10;
  499.                     collect -= 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
  500.                 }
  501.                 else if (collect <= 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30)
  502.                 {
  503.                     month_ = 11;
  504.                     collect -= 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
  505.                 }
  506.                 else
  507.                 {
  508.                     month_ = 12;
  509.                     collect -= 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30;
  510.                 }
  511.             }
  512.             else
  513.             {
  514.                 if (collect <= 31 + 28)
  515.                 {
  516.                     month_ = 2;
  517.                     collect -= 31;
  518.                 }
  519.                 else if (collect <= 31 + 28 + 31)
  520.                 {
  521.                     month_ = 3;
  522.                     collect -= 31 + 28;
  523.                 }
  524.                 else if (collect <= 31 + 28 + 31 + 30)
  525.                 {
  526.                     month_ = 4;
  527.                     collect -= 31 + 28 + 31;
  528.                 }
  529.                 else if (collect <= 31 + 28 + 31 + 30 + 31)
  530.                 {
  531.                     month_ = 5;
  532.                     collect -= 31 + 28 + 31 + 30;
  533.                 }
  534.                 else if (collect <= 31 + 28 + 31 + 30 + 31 + 30)
  535.                 {
  536.                     month_ = 6;
  537.                     collect -= 31 + 28 + 31 + 30 + 31;
  538.                 }
  539.                 else if (collect <= 31 + 28 + 31 + 30 + 31 + 30 + 31)
  540.                 {
  541.                     month_ = 7;
  542.                     collect -= 31 + 28 + 31 + 30 + 31 + 30;
  543.                 }
  544.                 else if (collect <= 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31)
  545.                 {
  546.                     month_ = 8;
  547.                     collect -= 31 + 28 + 31 + 30 + 31 + 30 + 31;
  548.                 }
  549.                 else if (collect <= 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30)
  550.                 {
  551.                     month_ = 9;
  552.                     collect -= 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31;
  553.                 }
  554.                 else if (collect <= 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31)
  555.                 {
  556.                     month_ = 10;
  557.                     collect -= 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
  558.                 }
  559.                 else if (collect <= 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30)
  560.                 {
  561.                     month_ = 11;
  562.                     collect -= 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
  563.                 }
  564.                 else
  565.                 {
  566.                     month_ = 12;
  567.                     collect -= 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30;
  568.                 }
  569.             }
  570.         }
  571.         day_ = collect;
  572.         return;
  573.     }
  574. }
  575.  
  576.  
  577.  
  578.  
  579. //main.cpp
  580.  
  581. #include <cstdio>
  582. #include <clocale>
  583. #include "Date.h"
  584.  
  585. int main()
  586. {
  587.     setlocale(LC_ALL, "Russian");
  588.     Date one(0, 0, 0, 0, 0, 0);
  589.     LL y = 0; // год
  590.     LL m = 0; // месяц
  591.     LL d = 0; // день
  592.     LL sec = 0; // изменение сек
  593.     LL days = 0; // изменение дней
  594.     LL s = 0; // сек
  595.     LL min = 0; // мин
  596.     LL h = 0; // часы
  597.     printf("Введи часы: ");
  598.     scanf("%lld", &h);
  599.     printf("Введи минуты: ");
  600.     scanf("%lld", &min);
  601.     printf("Введи секунды: ");
  602.     scanf("%lld", &s);
  603.     printf("Введи год: ");
  604.     scanf("%lld", &y);
  605.     printf("Введи месяц: ");
  606.     scanf("%lld", &m);
  607.     printf("Введи день: ");
  608.     scanf("%lld", &d);
  609.     one.set_date(y, m, d);
  610.     one.set_hours(h);
  611.     one.set_min(min);
  612.     one.set_sec(s);
  613.     printf("Введите кол-во секунд, на которое хотите изменить время: ");
  614.     scanf("%lld", &sec);
  615.     printf("Введите кол-во дней, на которое хотите изменить время: ");
  616.     scanf("%lld", &days);
  617.     one.change_sec(sec);
  618.     one.shift_day(days);
  619.     printf("Новая дата: год %lld : месяц %lld : день %lld\n часы %lld : минуты %lld : секунды %lld\n", one.get_year(), one.get_month(), one.get_day(), one.get_hours(), one.get_min(), one.get_sec());
  620.     return 0;
  621. }
Add Comment
Please, Sign In to add comment