Święta ruchome liczone od Wielkanocy

Kalendarz krok po kroku: święta - Podstawy C++ (C++)

Pozostałe święta ruchome mają stałą odległość od Wielkanocy: poniedziałek wielkanocny +1 dzień, Zielone Świątki +49, Boże Ciało +60. Dodawanie dni do daty jest proste na numerze dnia w roku (1 stycznia = 1): dayOfYear zamienia datę na numer, dateOfDay numer z powrotem na datę. Od tego kroku program używa tylko algorytmu Meeusa, więc pozostałe sposoby wypadają.

#include <iostream>
using namespace std;

// swieta stale: dzien, miesiac i nazwa (bez polskich liter - konsola)
const int FIXED = 10;
int fixedDay[FIXED] = {1, 6, 1, 3, 15, 1, 11, 24, 25, 26};
int fixedMonth[FIXED] = {1, 1, 5, 5, 8, 11, 11, 12, 12, 12};
char fixedName[FIXED][28] = {"Nowy Rok", "Trzech Kroli", "Swieto Pracy",
                             "Swieto Konstytucji", "Wniebowziecie NMP",
                             "Wszystkich Swietych", "Swieto Niepodleglosci",
                             "Wigilia", "Boze Narodzenie", "Drugi dzien Swiat"};

// data jako 5.04 (miesiac zawsze dwiema cyframi)
void printDate(int d, int m) {
  cout << d << "." << (m < 10 ? "0" : "") << m;
}

// numer swieta stalego w tablicy albo -1, gdy to zwykly dzien
int fixedHoliday(int d, int m, int y) {
  for (int i = 0; i < FIXED; i++) {
    if (fixedDay[i] == d && fixedMonth[i] == m) {
      if (i == 7 && y < 2025) {
        return -1; // Wigilia jest wolna od 2025 roku
      }
      return i;
    }
  }
  return -1;
}

bool isLeap(int y) {
  return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
}

int daysInMonth(int m, int y) {
  int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  if (m == 2 && isLeap(y)) {
    return 29;
  }
  return days[m - 1];
}

// dzien tygodnia: 0 = poniedzialek, ..., 6 = niedziela
// liczymy dni od 1 stycznia 1900 (to byl poniedzialek)
int weekday(int d, int m, int y) {
  int total = 0;
  for (int year = 1900; year < y; year++) {
    total += isLeap(year) ? 366 : 365;
  }
  for (int month = 1; month < m; month++) {
    total += daysInMonth(month, y);
  }
  total += d - 1;
  return total % 7;
}

// algorytm Meeusa: kazdy rok kalendarza gregorianskiego
int easterMeeus(int y) {
  int a = y % 19;
  int b = y / 100;
  int c = y % 100;
  int d = b / 4;
  int e = b % 4;
  int f = (b + 8) / 25;
  int g = (b - f + 1) / 3;
  int h = (19 * a + b - d - g + 15) % 30;
  int i = c / 4;
  int k = c % 4;
  int l = (32 + 2 * e + 2 * i - h - k) % 7;
  int m = (a + 11 * h + 22 * l) / 451;
  int month = (h + l - 7 * m + 114) / 31;
  int day = (h + l - 7 * m + 114) % 31 + 1;
  return month * 100 + day;
}

// numer dnia w roku: 1 = 1 stycznia
int dayOfYear(int d, int m, int y) {
  int n = d;
  for (int month = 1; month < m; month++) {
    n += daysInMonth(month, y);
  }
  return n;
}

// odwrotnie: numer dnia w roku -> miesiac * 100 + dzien
int dateOfDay(int n, int y) {
  int m = 1;
  while (n > daysInMonth(m, y)) {
    n -= daysInMonth(m, y);
    m++;
  }
  return m * 100 + n;
}

// swieta ruchome: ile dni po Wielkanocy
const int MOVABLE = 4;
int movableShift[MOVABLE] = {0, 1, 49, 60};
char movableName[MOVABLE][28] = {"Wielkanoc", "Poniedzialek Wielkanocny",
                                 "Zielone Swiatki", "Boze Cialo"};

void printEaster(int e) {
  printDate(e % 100, e / 100);
}

int main() {
  int y = 2026;
  int easter = easterMeeus(y);
  int start = dayOfYear(easter % 100, easter / 100, y);
  for (int i = 0; i < MOVABLE; i++) {
    printEaster(dateOfDay(start + movableShift[i], y));
    cout << " " << movableName[i] << endl;
  }
  return 0;
}

Ładowanie interaktywnego edytora... Jeśli się nie pojawi, włącz JavaScript.

Wszystkie lekcje kursu Podstawy C++·Zaloguj się, aby zapisać postęp na koncie.