123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- #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;
- }
|