Little_hobbit

date.cpp

Sep 3rd, 2020 (edited)
232
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.61 KB | None | 0 0
  1. /*
  2.  * Южный федеральный университет, ИКТИБ, кафедра МОП ЭВМ
  3.  * Гатауллин Руслан Рустемович
  4.  * Написано 04.09.2020
  5.  */
  6.  
  7. // Библиотеки ввода-вывода
  8. #include <iostream>
  9. #include <iomanip>
  10. // Заголовочный файл класса даты
  11. #include "date.h"
  12.  
  13. // Конструктор по умолчанию
  14. Date::Date() : _day(1), _mouth(1), _year(0)
  15. {}
  16.  
  17. // Конструктор из трех полей
  18. Date::Date(unsigned char day, unsigned char mouth, int year)
  19.         : _day(day), _mouth(mouth), _year(year)
  20. {}
  21.  
  22. // Конструктор копирования
  23. Date::Date(const Date &other) : _day(other._day), _mouth(other._mouth), _year(other._year)
  24. {}
  25.  
  26. // Потоковый вывод
  27. std::ostream &operator<<(std::ostream &os, Date const &to_out)
  28. {
  29.     os << std::setfill('0') << std::setw(2) << (short) to_out._day << '.';
  30.     os << std::setfill('0') << std::setw(2) << (short) to_out._mouth << '.';
  31.     os << std::setfill('0') << std::setw(4) << to_out._year;
  32.     return os;
  33. }
  34.  
  35. // Потоковый ввод
  36. std::istream &operator>>(std::istream &is, Date &to_in)
  37. {
  38.     int day;
  39.     is >> day;
  40.     is.ignore(1);
  41.  
  42.     int mouth;
  43.     is >> mouth;
  44.     is.ignore(1);
  45.  
  46.     int year;
  47.     is >> year;
  48.  
  49.     // Проверяем на ошибки
  50.     if (mouth <= 0 || mouth > 12)
  51.         throw std::runtime_error("неправильный номер месяца");
  52.     if (day <= 0 || day > mouths[mouth - 1])
  53.         throw std::runtime_error("неправильный номер дня");
  54.  
  55.     to_in._year = year;
  56.     to_in._mouth = mouth;
  57.     to_in._day = day;
  58.  
  59.     return is;
  60. }
  61.  
  62. // Процедура прибавления к дате целой константы
  63. Date Date::operator+(unsigned long int d)
  64. {
  65.     Date ans = *this;
  66.     d += ans._day;
  67.  
  68.     // Пробегаем лишние года, УЧИТЫВАЯ(!) високосные
  69.     while (d > 366)
  70.     {
  71.         // просчитываем, проходим ли мы высокосный год с 1 лишним днем
  72.         d -= ((ans._year % 4 == 0) &&
  73.               ((ans._year % 100 != 0) || (ans._year % 400 == 0)) &&
  74.               (ans._mouth <= 2) && (ans._day < 29)) ? 366 : 365;
  75.         // Увеличиваем количество годов
  76.         ans._year++;
  77.         // Проверяем, не прошли ли мы случайно 29-е февраля
  78.         if ((ans._year % 4 == 0) &&
  79.             ((ans._year % 100 != 0) || (ans._year % 400 == 0)) &&
  80.             (ans._mouth > 2))
  81.             d--;
  82.     }
  83.  
  84.     // Пробегаем лишние месяца, основываясь
  85.     // на массиве констрант, где каждый i-й элемент - количкство дней в i+1 месяце
  86.     while (d > mouths[ans._mouth - 1])
  87.     {
  88.         // Проверяем, пробегаем ли феврать
  89.         if (ans._mouth == 2)
  90.         {
  91.             // Если пробегаем високосный февраль, отнимаем 29 дней, иначе 28
  92.             d -= ((ans._year % 4 == 0) && ((ans._year % 100 != 0) || (ans._year % 400 == 0))) ? 29 : 28;
  93.         }
  94.         else
  95.             d -= mouths[ans._mouth - 1]; // Если же не пробегаем февраль, отнимаем обычное количество дней
  96.         // увеличиваем количество месяцев
  97.         ans._mouth++;
  98.         // Если проскочили декабрь, ставим следующий год
  99.         if (ans._mouth > 12)
  100.         {
  101.             ans._mouth = 1;
  102.             ans._year++;
  103.         }
  104.     }
  105.     // В конечном итоге ставим день месяца
  106.     ans._day = d;
  107.     return ans;
  108. }
  109.  
  110. // Функция определения дня недели по дате
  111. // Алгоритм взят с википедии и способен определять день недели
  112. // по дате с момента принятия нынешнего карендаря
  113. // НЕ РАБОТАЕТ для определения дня недели в России до 1918 года (год принятия григориянского календаря)
  114. unsigned short Date::dayOfWeek() const
  115. {
  116.     unsigned long long year = _year, mouth;
  117.     if (_mouth == 1 || _mouth == 2)
  118.     {
  119.         year = _year - 1;
  120.         mouth = _mouth + 10;
  121.     }
  122.     else
  123.         mouth = _mouth - 2;
  124.     unsigned short a = (_day + (31 * mouth) / 12 + year + year / 4 - year / 100 + year / 400) % 7;
  125.     return (a == 0) ? 7 : a;
  126. }
  127.  
  128. // Получение поля дня
  129. unsigned short Date::get_day() const
  130. {
  131.     return _day;
  132. }
  133.  
  134. // Получение закрытого поля месяца
  135. unsigned short Date::get_mouth() const
  136. {
  137.     return _mouth;
  138. }
  139.  
  140. // Получение закрытого поля года
  141. int Date::get_year() const
  142. {
  143.     return _year;
  144. }
  145.  
  146. // Передача значения закрытому полю _day
  147. void Date::set_day(unsigned short day)
  148. {
  149.     if (day >= mouths[_mouth - 1] || day == 0) throw std::runtime_error("неправильный номер дня");
  150.     _day = day;
  151. }
  152.  
  153. // Передача значения закрытому полю _mouth
  154. void Date::set_mouth(unsigned short mouth)
  155. {
  156.     if (mouth > 12 || mouth == 0) throw std::runtime_error("неправильный номер месяца");
  157.     _mouth = mouth;
  158. }
  159.  
  160. // Передача значения закрытому полю _year
  161. void Date::set_year(int year)
  162. {
  163.     _year = year;
  164. }
  165.  
Advertisement
Add Comment
Please, Sign In to add comment