#pragma once

class Date {
public:
	Date(int year, int month, int day) {
		y = year;
		m = month;
		d = day;
	}
	bool IsLeap() const {
		return y % 400 != 0 ? y % 100 != 0 ? y % 4 == 0 ? true : false : false : true;
	}
	std::string ToString() const {
		std::string a = d < 10 ? "0" + std::to_string(d) : std::to_string(d);
		a += "." + (m < 10 ? "0" + std::to_string(m) : std::to_string(m));
		a += "." + (y < 1000 ? y < 100 ? y < 10 ? "000" + std::to_string(y) : "00" + std::to_string(y) : "0" + std::to_string(y) : std::to_string(y));
		return a;
	}
	Date DaysLater(int days) const {
		int64_t yy = y, mm = m, dd = d + days;
		while (true) {
			if (mm > 12) {
				mm = 1;
				yy++;
			}
			if (mm == 2 && ((dd > 28 && yy % 4 != 0) || (dd > 29 && yy % 4 == 0))) {
				dd -= y % 4 == 0 ? 29 : 28;
				mm++;
				continue;
			}
			if (dd > 30 && (mm == 4 || mm == 6 || mm == 9 || mm == 11)) {
				dd -= 30;
				mm++;
				continue;
			}
			if (dd > 31 && (mm == 1 || mm == 3 || mm == 5 || mm == 7 || mm == 8 || mm == 10 || mm == 12)) {
				dd -= 31;
				mm++;
				continue;
			}
			break;
		}
		Date a(yy, mm, dd);
		return a;
	}
	int DaysLeft(const Date& date) const {
		int64_t v = 0, dif_d = - d + date.d;
		for (int64_t i = y; i < date.y; i++) {
			if (i % 4 == 0) v++;
		}
		for (int64_t i = 1; i < m; i++) {
			if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12) dif_d -= 31;
			else if (i == 4 || i == 6 || i == 9 || i == 11) dif_d -= 30;
			else dif_d -= y % 4 == 0 ? 29 : 28;
		}
		for (int64_t i = 1; i < date.m; i++) {
			if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12) dif_d += 31;
			else if (i == 4 || i == 6 || i == 9 || i == 11) dif_d += 30;
			else dif_d += date.y % 4 == 0 ? 29 : 28;
		}
		return 365 * (date.y - y) + v + dif_d;
	}

	int64_t y, m, d;
};