#include #include #include #include class Date { private: int day, month, year; std::stringstream str; constexpr static const int leap[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; constexpr static const int not_leap[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; struct date { int year, month, day; }; int number_by_date() { int year = this->year - 1; int kinda_answer = 365 * year + year / 4 - year / 100 + year / 400; for (int i = 0; i < month - 1; i++) { if (IsLeap()) { kinda_answer += leap[i]; } else { kinda_answer += not_leap[i]; } } kinda_answer += day; return kinda_answer; } static date date_by_number(int number) { int min_year = 1, max_year = 4000; while (max_year != min_year) { int mid = (min_year + max_year) / 2; if (number - (365 * mid + mid / 4 - mid / 100 + mid / 400) < 0) { max_year = mid; } else { min_year = mid + 1; } } int year = min_year - 1; number -= 365 * year + year / 4 - year / 100 + year / 400; year++; bool is_leap = year % 400 == 0 || year % 4 == 0 && year % 100 != 0; int month = 1; for (int i = 0; i < 12; i++) { if (is_leap) { if (number > leap[i]) { number -= leap[i]; month++; } else { break; } } else { if (number > not_leap[i]) { number -= not_leap[i]; month++; } else { break; } } } if (month == 13) { year += 1; month = 1; } int day = number; return date{year, month, day}; } public: Date(int year, int month, int day) { this->year = year; this->month = month; this->day = day; } bool IsLeap() { if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0) { return true; } return false; } std::string ToString() { str << std::setw(2) << std::setfill('0') << day << std::setw(0) << "." << std::setw(2) << month << std::setw(0) << "." << std::setw(4) << year; std::string answer; str >> answer; return answer; } Date DaysLater(int days) { auto smth = date_by_number(number_by_date() + days); return {smth.year, smth.month, smth.day}; } int DaysLeft(Date date) { return date.number_by_date() - number_by_date(); } };