datetime.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. #include "datetime.h"
  2. #include <string.h>
  3. //Конструкторы
  4. //создать из трёх чисел
  5. void date::create_from_numbers(int ayear, int amonth, int adate) {
  6. unsigned long long a, y, m;
  7. //промежуточные
  8. a = (14 - (double)amonth) / 12;
  9. y = ayear + 4800 - a;
  10. m = amonth + 12 * a - 3;
  11. julian = adate + (153 * m + 2) / 5 + 365 * y + y / 4 - 32083;
  12. //обратно в дату
  13. date_from_julian();
  14. if (ayear != year || amonth != month || adate != day) {
  15. cout << year << " " << month << " " << day;
  16. throw date_exception();
  17. }
  18. };
  19. //в дату из юлианского
  20. void date::date_from_julian() {
  21. unsigned long long m, c, d, e;
  22. c = julian + 32082;
  23. d = (4 * c + 3) / 1461;
  24. e = c - (1461 * d) / 4;
  25. m = (5 * e + 2) / 153;
  26. day = e - (153 * m + 2) / 5 + 1;
  27. month = m + 3 - 12 * (m / 10);
  28. year = d - 4800 + m / 10;
  29. }
  30. //конструктор даты из интов
  31. date::date(int ayear, int amonth, int adate) {
  32. create_from_numbers(ayear, amonth, adate);
  33. }
  34. //конструктор даты из массива символов
  35. date::date(char word[]) {
  36. int index = 0, max = 0, spaces = 0, dots = 0;
  37. while (word[index] != '\0') {
  38. max = max > (int)(word[index]) ? max : (int)(word[index]);
  39. spaces = word[index] == ' ' ? spaces + 1 : spaces;
  40. dots = word[index] == '.' ? dots + 1 : dots;
  41. index++;
  42. }
  43. //конструктор типа dd.mm.yyyy
  44. if (max <= 57 && max >= 46 && dots == 2) {
  45. date_split(word, '.');
  46. }
  47. //конструктор типа d месяц y
  48. else if (spaces == 2) {
  49. date_words(word);
  50. }
  51. else {
  52. throw date_exception();
  53. }
  54. }
  55. //по умолчанию
  56. date::date() {
  57. create_from_numbers(0, 1, 1);
  58. }
  59. //вспомогательные
  60. //перевод в инт
  61. int char_to_int(char word[], int index, char splitter) {
  62. index--;
  63. int dec = 1, ret = 0;
  64. while (index != -1 && word[index] != splitter) {
  65. int cur = (int)(word[index]) - 48;
  66. ret += cur * dec;
  67. dec *= 10;
  68. index--;
  69. }
  70. return ret;
  71. }
  72. //перевод месяца
  73. int word_to_int(char word[], int index, char splitter) {
  74. index++;
  75. int cur_index = index;
  76. char word_tmp[80];
  77. while (word[cur_index] != splitter) {
  78. word_tmp[cur_index - index] = word[cur_index];
  79. cur_index++;
  80. }
  81. for (int i = 0; i <= 11; i++) {
  82. bool swch = 1;
  83. cur_index = 0;
  84. while (word_tmp[cur_index] != -52) {
  85. if (word_tmp[cur_index] != MONTHS[i][cur_index]) {
  86. swch = 0;
  87. break;
  88. }
  89. if (swch)
  90. return i + 1;
  91. cur_index++;
  92. }
  93. }
  94. throw date_exception();
  95. }
  96. //разница дней
  97. const unsigned long long& date::operator-(const date& d)
  98. {
  99. // TODO: вставьте здесь оператор return
  100. unsigned long long j1, j2;
  101. j1 = this->julian;
  102. j2 = d.julian;
  103. return j1 > j2 ? (j1 - j2) : (j2 - j1);
  104. }
  105. const bool& date::operator<(const date& d)
  106. {
  107. return julian < d.julian;
  108. }
  109. const bool& date::operator>=(const date& d)
  110. {
  111. return julian >= d.julian;
  112. }
  113. const bool& date::operator>(const date& d)
  114. {
  115. return julian > d.julian;
  116. }
  117. const bool& date::operator<=(const date& d)
  118. {
  119. return julian <= d.julian;
  120. }
  121. const bool& date::operator==(const date& d)
  122. {
  123. return julian == d.julian;
  124. }
  125. //получить день недели
  126. void date::week_day() {
  127. int index = 0;
  128. while (DAYS[julian % 7 + 1][index] != '\0') {
  129. cout << DAYS[julian % 7 + 1][index];
  130. index++;
  131. }
  132. cout << endl;
  133. }
  134. //пасха
  135. const date& date::get_dates_year_easter() {
  136. int a = year % 19;
  137. int b = year % 4;
  138. int c = year % 7;
  139. int d = (19 * a + 15) % 30;
  140. int e = (2 * b + 4 * c + 6 * d + 6)%7;
  141. int f = d + e;
  142. if (f<=9)
  143. return date(year,3,22+f);
  144. return date(year, 4, f - 9);
  145. }
  146. //приватные
  147. //формат dd mm yyyy
  148. void date::date_split(char word[], char splitter) {
  149. int index = 0, swich = 0;
  150. int full_date[3];
  151. while (word[index] != '\0') {
  152. if (word[index] == splitter) {
  153. full_date[swich] = char_to_int(word, index, splitter);
  154. swich++;
  155. }
  156. index++;
  157. }
  158. full_date[2] = char_to_int(word, index, splitter);
  159. full_date[2] = full_date[2] / 100 == 0 ? full_date[2] + 2000 : full_date[2];
  160. create_from_numbers(full_date[2], full_date[1], full_date[0]);
  161. delete[] word;
  162. }
  163. //формат 1 месяц 2021
  164. void date::date_words(char word[])
  165. {
  166. char splitter = ' ';
  167. int full_date[3];
  168. int index = 0;
  169. bool swch = 1;
  170. while (word[index] != '\0') {
  171. if (word[index] == splitter && swch) {
  172. full_date[0] = char_to_int(word, index, splitter);
  173. full_date[1] = word_to_int(word, index, splitter);
  174. swch = !swch;
  175. }
  176. index++;
  177. }
  178. full_date[2] = char_to_int(word, index, splitter);
  179. create_from_numbers(full_date[2], full_date[1], full_date[0]);
  180. delete[] word;
  181. }
  182. ostream& operator<<(ostream& os, date& d)
  183. {
  184. os << d.day << "." << d.month << "." << d.year;
  185. return os;
  186. }