#include <string>
#include <cstring>
class Date {
public:
Date(int year, int month, int day)
: _year(year), _month(static_cast<Month>(month)), _day(day) {
if (!isValidDate())
setDefaultDate();
}
bool IsLeap() const {
return (_year % 400 == 0) || (_year % 4 == 0 && _year % 100 != 0);
}
std::string ToString() const {
std::string result{};
if (_day < 10)
result += "0";
result += std::to_string(_day);
result += '.';
auto mon = static_cast<int> (_month);
if (mon < 10)
result += "0";
result += std::to_string(mon);
result += '.';
std::string y = to_string(_year);
while (strlen((y).c_str()) < 4) {
result += "0";
y += '0';
}
result += std::to_string(_year);
return result;
}
Date DaysLater(int days) const {
Date newDate = *this;
for (size_t i = 0; i < static_cast<size_t> (days); ++i)
newDate.addDay();
return newDate;
}
int DaysLeft(const Date &date) const {
int counter{};
Date greaterDate = *this;
Date smallestDate = date;
if (!greaterDate.greater(date)) {
greaterDate = date;
smallestDate = *this;
}
if (greaterDate.equal(smallestDate))
return 0;
do {
smallestDate.addDay();
counter++;
} while (!greaterDate.equal(smallestDate));
return counter;
}
enum class Month {
Jan = 1, Feb, Mar, Apr, May,
Jun, Jul, Aug, Sep, Oct, Nov, Dec
};
private:
bool greater(const Date &b) {
return (strcmp(this->ToString().c_str(), b.ToString().c_str()) > 0);
}
bool equal(const Date &b) {
return this->_year == b._year && this->_month == b._month
&& this->_day == b._day;
}
int maxDaysInMonth() const {
auto mon = static_cast<int>(_month);
if (IsLeap() && mon == static_cast<int> (Month::Feb))
return 29;
else if (!IsLeap() && mon == static_cast<int> (Month::Feb))
return 28;
else
return 30 + ((mon + mon / 8) % 2);
}
bool isValidDate() const {
return _day >= 1 && _day <= maxDaysInMonth();
}
void setDefaultDate() {
_year = 1970;
_month = Month::Jan;
_day = 1;
}
void addMonth() {
if (_month == Month::Dec) {
_month = Month::Jan;
_year++;
} else {
_month = static_cast<Month>(static_cast<int>(_month) + 1);
}
}
void addDay() {
if (_day >= maxDaysInMonth()) {
_day = 1;
addMonth();
} else
_day++;
}
private:
int _year;
Month _month;
int _day;
};