#pragma once

long JDay(int year, int month, int day) {
    if (month <= 2) {
        year--;
        month += 12;
    };
    unsigned long J;
    int A = year / 100;
    A = 2 - A + (A / 4);
    J = 1461L * long(year);
    J /= 4L;
    unsigned long K = 306001L * long(month + 1);
    K /= 10000L;
    J += K + day + 1720995L + A;
    return J;
}

void GDate(long JD, int& y, int& m, int& d) {
    unsigned long A = (JD * 4L - 7468865L) / 146097L;
    A = (JD > 2299160) ? JD + 1 + A - (A / 4L) : JD;
    long B = A + 1524;
    long C = (B * 20L - 2442L) / 7305L;
    long D = (C * 1461L) / 4L;
    long E = (10000L * (B - D)) / 306001L;
    d = int(B - D - ((E * 306001L) / 10000L));
    m = int((E <= 13) ? E - 1 : E - 13);
    y = int(C - ((m > 2) ? 4716 : 4715));
}

class Date {
public:
    Date(int y = 0, int m = 0, int d = 0) {
        day = d;
        month = m;
        year = y;
    }

    bool IsLeap() const {
        if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
            return true;
        return false;
    }

    std::string ToString() {
        std::string dates = "";
        dates += day < 10 ? (+"0" + std::to_string(day) + ".") :
            (std::to_string(day)) + ".";
        dates += month < 10 ? (+"0" + std::to_string(month) + ".") :
            (std::to_string(month)) + ".";

        dates += year > 999 ? std::to_string(year) : year > 99 ?
            (+"0" + std::to_string(year)) : year > 9 ?
            (+"00" + std::to_string(year)) :
            (+"000" + std::to_string(year));

        return dates;
    }

    Date DaysLater(int days) const {
        Date dat;
        int y, m, d;
        long jday = JDay(year, month, day);
        GDate(jday + days, y, m, d);
        dat.day = d;
        dat.month = m;
        dat.year = y;
        return dat;
    }

    int DaysLeft(const Date& date) const {
        long jday1 = JDay(year, month, day);
        long jday2 = JDay(date.year, date.month, date.day);
        return jday2 - jday1;
    }

private:
    int day;
    int month;
    int year;
};