datetime.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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. //получить день недели
  106. void date::week_day() {
  107. int index = 0;
  108. while (DAYS[julian % 7 + 1][index] != '\0') {
  109. cout << DAYS[julian % 7 + 1][index];
  110. index++;
  111. }
  112. cout << endl;
  113. }
  114. //пасха
  115. const date& date::get_dates_year_easter() {
  116. int a = year % 19;
  117. int b = year % 4;
  118. int c = year % 7;
  119. int d = (19 * a + 15) % 30;
  120. int e = (2 * b + 4 * c + 6 * d + 6)%7;
  121. int f = d + e;
  122. if (f<=9)
  123. return date(year,3,22+f);
  124. return date(year, 4, f - 9);
  125. }
  126. //приватные
  127. //формат dd mm yyyy
  128. void date::date_split(char word[], char splitter) {
  129. int index = 0, swich = 0;
  130. int full_date[3];
  131. while (word[index] != '\0') {
  132. if (word[index] == splitter) {
  133. full_date[swich] = char_to_int(word, index, splitter);
  134. swich++;
  135. }
  136. index++;
  137. }
  138. full_date[2] = char_to_int(word, index, splitter);
  139. full_date[2] = full_date[2] / 100 == 0 ? full_date[2] + 2000 : full_date[2];
  140. create_from_numbers(full_date[2], full_date[1], full_date[0]);
  141. delete[] word;
  142. }
  143. //формат 1 месяц 2021
  144. void date::date_words(char word[])
  145. {
  146. char splitter = ' ';
  147. int full_date[3];
  148. int index = 0;
  149. bool swch = 1;
  150. while (word[index] != '\0') {
  151. if (word[index] == splitter && swch) {
  152. full_date[0] = char_to_int(word, index, splitter);
  153. full_date[1] = word_to_int(word, index, splitter);
  154. swch = !swch;
  155. }
  156. index++;
  157. }
  158. full_date[2] = char_to_int(word, index, splitter);
  159. create_from_numbers(full_date[2], full_date[1], full_date[0]);
  160. delete[] word;
  161. }
  162. ostream& operator<<(ostream& os, date& d)
  163. {
  164. os << d.day << "." << d.month << "." << d.year;
  165. return os;
  166. }