Gregorian Gregorian::subtract_years(Gregorian const& date, year_t n) { auto y = date.year() - n; auto m = date.month(); auto d = date.day(); if (m == 2 && d == 29 && !is_gregorian_leapyear(y)) d = 28; return Gregorian(year_t(y), month_t(m), day_t(d), date.hour(), date.minute(), date.second()); }
Gregorian Gregorian::add_months(Gregorian const& date, month_t n) { /*auto m = date.month() + n; auto y = date.year() + (m - 1) / 12; m = (m - 1) % 12 + 1; auto d = gregorian_days_in_month(m, is_gregorian_leapyear(y)); if (date.day() < d) d = date.day();*/ year_t y = date.year() + n / 12; month_t m = date.month() + n % 12; auto adjust = (m - 1) / 12 + (m - 12) / 12; y = y + adjust; m = m - adjust * 12; day_t d = min(date.day(), gregorian_days_in_month(m, is_gregorian_leapyear(y))); return Gregorian(y, month_t(m), d, date.hour(), date.minute(), date.second()); }
Gregorian Gregorian::subtract_months(Gregorian const& date, month_t n) { //auto m = date.month() - n; //auto y = date.year() - (m - 1) / 12; //m = (m - 1) % 12 + 1; //auto d = gregorian_days_in_month(m, is_gregorian_leapyear(y)); //if (date.day() < d) // d = date.day(); //return Gregorian(y, month_t(m), d, date.hour(), date.minute(), date.second()); year_t y = date.year() - n / 12; month_t m = date.month() - n % 12; auto adjust = (m - 1) / 12 + (m - 12) / 12; y = y + adjust; m = m - adjust * 12; day_t d = min(date.day(), gregorian_days_in_month(m, is_gregorian_leapyear(y))); return Gregorian(y, month_t(m), d, date.hour(), date.minute(), date.second()); }
inline second_t second(Gregorian const& greg) { return greg.second(); }