#pragma once
#include <string>
int64_t JDay(int year, int month, int day) {
if (month <= 2) {
year--;
month += 12;
}
int64_t J;
int A = year / 100;
A = 2 - A + (A / 4);
J = 1461L * int64_t(year);
J /= 4L;
int64_t K = 306001L * int64_t(month + 1);
K /= 10000L;
J += K + day + 1720995L + A;
return J;
}
void GDate(int64_t JD, int& y, int& m, int& d) {
int64_t A = (JD * 4L - 7468865L) / 146097L;
A = (JD > 2299160) ? JD + 1 + A - (A / 4L) : JD;
int64_t B = A + 1524;
int64_t C = (B * 20L - 2442L) / 7305L;
int64_t D = (C * 1461L) / 4L;
int64_t E = (10000L * (B - D)) / 306001L;
d = static_cast<int>(B - D - ((E * 306001L) / 10000L));
m = static_cast<int>((E <= 13) ? E - 1 : E - 13);
y = static_cast<int>(C - ((m > 2) ? 4716 : 4715));
}
class Date {
public:
explicit 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 {
int y, m, d;
int64_t jday = JDay(year, month, day);
GDate(jday + days, y, m, d);
Date dat(y, m, d);
return dat;
}
int DaysLeft(const Date& date) const {
int64_t jday1 = JDay(year, month, day);
int64_t jday2 = JDay(date.year, date.month, date.day);
return jday2 - jday1;
}
private:
int day;
int month;
int year;
};