|
@@ -0,0 +1,255 @@
|
|
|
+#include "datetime.h"
|
|
|
+#include <string.h>
|
|
|
+
|
|
|
+
|
|
|
+//Конструкторы
|
|
|
+
|
|
|
+//создать из трёх чисел
|
|
|
+void date::create_from_numbers(int ayear, int amonth, int adate) {
|
|
|
+ unsigned long long a, y, m;
|
|
|
+
|
|
|
+
|
|
|
+ //промежуточные
|
|
|
+ a = (14 - (double)amonth) / 12;
|
|
|
+
|
|
|
+ y = ayear + 4800 - a;
|
|
|
+
|
|
|
+ m = amonth + 12 * a - 3;
|
|
|
+
|
|
|
+ julian = adate + (153 * m + 2) / 5 + 365 * y + y / 4 - 32083;
|
|
|
+
|
|
|
+
|
|
|
+ //обратно в дату
|
|
|
+ date_from_julian();
|
|
|
+
|
|
|
+
|
|
|
+ if (ayear != year || amonth != month || adate != day) {
|
|
|
+
|
|
|
+ cout << year << " " << month << " " << day;
|
|
|
+ throw date_exception();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+};
|
|
|
+//в дату из юлианского
|
|
|
+void date::date_from_julian() {
|
|
|
+ unsigned long long m, c, d, e;
|
|
|
+ c = julian + 32082;
|
|
|
+
|
|
|
+ d = (4 * c + 3) / 1461;
|
|
|
+
|
|
|
+ e = c - (1461 * d) / 4;
|
|
|
+
|
|
|
+ m = (5 * e + 2) / 153;
|
|
|
+
|
|
|
+ day = e - (153 * m + 2) / 5 + 1;
|
|
|
+
|
|
|
+ month = m + 3 - 12 * (m / 10);
|
|
|
+
|
|
|
+ year = d - 4800 + m / 10;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+//конструктор даты из интов
|
|
|
+date::date(int ayear, int amonth, int adate) {
|
|
|
+ create_from_numbers(ayear, amonth, adate);
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+//конструктор даты из массива символов
|
|
|
+date::date(char word[]) {
|
|
|
+ int index = 0, max = 0, spaces = 0, dots = 0;
|
|
|
+ while (word[index] != '\0') {
|
|
|
+ max = max > (int)(word[index]) ? max : (int)(word[index]);
|
|
|
+ spaces = word[index] == ' ' ? spaces + 1 : spaces;
|
|
|
+ dots = word[index] == '.' ? dots + 1 : dots;
|
|
|
+ index++;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //конструктор типа dd.mm.yyyy
|
|
|
+ if (max <= 57 && max >= 46 && dots == 2) {
|
|
|
+ date_split(word, '.');
|
|
|
+ }
|
|
|
+ //конструктор типа d месяц y
|
|
|
+ else if (spaces == 2) {
|
|
|
+ date_words(word);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ throw date_exception();
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+//по умолчанию
|
|
|
+date::date() {
|
|
|
+ create_from_numbers(0, 1, 1);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//вспомогательные
|
|
|
+//перевод в инт
|
|
|
+int char_to_int(char word[], int index, char splitter) {
|
|
|
+ index--;
|
|
|
+ int dec = 1, ret = 0;
|
|
|
+ while (index != -1 && word[index] != splitter) {
|
|
|
+ int cur = (int)(word[index]) - 48;
|
|
|
+ ret += cur * dec;
|
|
|
+
|
|
|
+
|
|
|
+ dec *= 10;
|
|
|
+ index--;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+//перевод месяца
|
|
|
+int word_to_int(char word[], int index, char splitter) {
|
|
|
+ index++;
|
|
|
+ int cur_index = index;
|
|
|
+ char word_tmp[80];
|
|
|
+ while (word[cur_index] != splitter) {
|
|
|
+ word_tmp[cur_index - index] = word[cur_index];
|
|
|
+ cur_index++;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ for (int i = 0; i <= 11; i++) {
|
|
|
+ bool swch = 1;
|
|
|
+ cur_index = 0;
|
|
|
+ while (word_tmp[cur_index] != -52) {
|
|
|
+
|
|
|
+ if (word_tmp[cur_index] != MONTHS[i][cur_index]) {
|
|
|
+ swch = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (swch)
|
|
|
+ return i + 1;
|
|
|
+ cur_index++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ throw date_exception();
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//разница дней
|
|
|
+const unsigned long long& date::operator-(const date& d)
|
|
|
+{
|
|
|
+ // TODO: вставьте здесь оператор return
|
|
|
+ unsigned long long j1, j2;
|
|
|
+ j1 = this->julian;
|
|
|
+ j2 = d.julian;
|
|
|
+
|
|
|
+
|
|
|
+ return j1 > j2 ? (j1 - j2) : (j2 - j1);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//получить день недели
|
|
|
+void date::week_day() {
|
|
|
+ int index = 0;
|
|
|
+ while (DAYS[julian % 7 + 1][index] != '\0') {
|
|
|
+ cout << DAYS[julian % 7 + 1][index];
|
|
|
+ index++;
|
|
|
+ }
|
|
|
+ cout << endl;
|
|
|
+}
|
|
|
+
|
|
|
+//пасха
|
|
|
+const date& date::get_dates_year_easter() {
|
|
|
+ int a = year % 19;
|
|
|
+ int b = year % 4;
|
|
|
+ int c = year % 7;
|
|
|
+ int d = (19 * a + 15) % 30;
|
|
|
+ int e = (2 * b + 4 * c + 6 * d + 6)%7;
|
|
|
+ int f = d + e;
|
|
|
+
|
|
|
+
|
|
|
+ if (f<=9)
|
|
|
+ return date(year,3,22+f);
|
|
|
+ return date(year, 4, f - 9);
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//приватные
|
|
|
+
|
|
|
+//формат dd mm yyyy
|
|
|
+void date::date_split(char word[], char splitter) {
|
|
|
+ int index = 0, swich = 0;
|
|
|
+
|
|
|
+ int full_date[3];
|
|
|
+
|
|
|
+ while (word[index] != '\0') {
|
|
|
+ if (word[index] == splitter) {
|
|
|
+ full_date[swich] = char_to_int(word, index, splitter);
|
|
|
+ swich++;
|
|
|
+ }
|
|
|
+
|
|
|
+ index++;
|
|
|
+ }
|
|
|
+ full_date[2] = char_to_int(word, index, splitter);
|
|
|
+
|
|
|
+ full_date[2] = full_date[2] / 100 == 0 ? full_date[2] + 2000 : full_date[2];
|
|
|
+
|
|
|
+ create_from_numbers(full_date[2], full_date[1], full_date[0]);
|
|
|
+
|
|
|
+ delete[] word;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//формат 1 месяц 2021
|
|
|
+void date::date_words(char word[])
|
|
|
+{
|
|
|
+ char splitter = ' ';
|
|
|
+ int full_date[3];
|
|
|
+ int index = 0;
|
|
|
+ bool swch = 1;
|
|
|
+
|
|
|
+
|
|
|
+ while (word[index] != '\0') {
|
|
|
+
|
|
|
+ if (word[index] == splitter && swch) {
|
|
|
+
|
|
|
+ full_date[0] = char_to_int(word, index, splitter);
|
|
|
+ full_date[1] = word_to_int(word, index, splitter);
|
|
|
+
|
|
|
+ swch = !swch;
|
|
|
+ }
|
|
|
+
|
|
|
+ index++;
|
|
|
+
|
|
|
+ }
|
|
|
+ full_date[2] = char_to_int(word, index, splitter);
|
|
|
+
|
|
|
+ create_from_numbers(full_date[2], full_date[1], full_date[0]);
|
|
|
+ delete[] word;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+ostream& operator<<(ostream& os, date& d)
|
|
|
+{
|
|
|
+ os << d.day << "." << d.month << "." << d.year;
|
|
|
+ return os;
|
|
|
+}
|