Skip to Content

Calendar

struct calendar { int sy; calendar(int sy = 1600) : sy(sy) {} int idx(int y, int m, int d) { return (y - sy) * 365 + count_leap(sy, y - 1) + count_days_month(1, m - 1, leap(y)) + d - 1; } array<int, 3> ymd(int i) { array<int, 3> ret; ret[0] = sy + i / 365.2422; while (idx(ret[0], 1, 1) - 1 >= i)ret[0]--; while (idx(ret[0] + 1, 1, 1) <= i)ret[0]++; i -= (ret[0] - sy) * 365 + count_leap(sy, ret[0] - 1); ret[1] = max(1, i / 31); while (count_days_month(1, ret[1], leap(ret[0])) <= i) ret[1]++; i -= count_days_month(1, ret[1] - 1, leap(ret[0])); ret[2] = i + 1; return ret; } int advance_month(int i) { auto[y, m, d] = ymd(i); int nm = m % 12 + 1; if (month_cnt[m] <= month_cnt[nm]) return m == 12 ? idx(y + 1, 1, d) : idx(y, m + 1, d); else return -1; } static constexpr int month_cnt[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, month_psum[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; static int count_days_month(int m1, int m2, bool is_leap) { if (m1 > m2) return 0; return month_psum[m2] - month_psum[m1 - 1] + (is_leap && m1 <= 2 && 2 <= m2); } static int count_leap(int y1, int y2) { if (y1 > y2) return 0; return y2 / 4 - (y1 - 1) / 4 - (y2 / 100 - (y1 - 1) / 100) + y2 / 400 - (y1 - 1) / 400; } static bool leap(int y) { if (y % 100 == 0) return y % 400 == 0; return y % 4 == 0; } static int day_of_week(int y, int m, int d) { if (m < 3) y--; m = (m + 9) % 12 + 1; int _c = y / 100, _y = y % 100; return ((d + int(2.6 * m - 0.2) - 2 * _c + _y + _c / 4 + _y / 4) % 7 + 7) % 7; } };
  • week calculator
int week(int y, int m, int d) { if (m < 3) y--; m = (m + 9) % 12 + 1; int _c = y / 100, _y = y % 100; return ((d + int(2.6 * m - 0.2) - 2 * _c + _y + _c / 4 + _y / 4) % 7 + 7) % 7; }
Last updated on