Jeszcze rok temu pandemia zaprzątała nasze myśli. 🗓️ 🦠 Dzisiaj temat ten przeszedł do lamusa. Można zaryzykować stwierdzenie, że wracamy do normalności. Jednak wydarzenia u naszych wschodnich sąsiadów przyniosły nowe obawy. Trudno jest przejść obojętnie wobec bólu, cierpienia i śmierci niewinnych osób. Wiedząc, że to wcale nie musiało się wydarzyć, że to zależy tylko od woli człowieka. Znaleźliśmy się w czasie i miejscu kiedy to

Ludzie ludziom zgotowali ten los

Z. Nałkowska “Medaliony”

Nie traćmy jednak nadziei, że te spokojniejsze czasy nadejdą, że są “tuż za rogiem”.

I właśnie od takich życzeń chcemy zacząć… aby te normalne, dobre dni czekały na nas wszystkich “tuż za rogiem”, aby były na wyciągnięcie ręki. Niech wszelkie troski i niepokoje zejdą na dalszy plan, a w ich miejsce zagoszczą radość i szczęście. Niech dni upłyną w spokoju i harmonii. Niech ten czas pozwoli odpocząć zarówno fizycznie, jak i psychicznie. Życzymy Wam cudownych chwil w gronie najbliższych.

Wesołego Alleluja! 🥚 🐇 🐤 🐏


Słowo się rzekło, czas go dotrzymać… ⏰

Powracamy do tematu wyliczania daty Świąt Wielkanocnych. Zgodnie z obietnicą daną w artykule Ruby Easter date, gdzie pisaliśmy o rozwiązaniu Gaussa, tym razem wykorzystamy metodę Meeusa/Jonesa/Butchera. Przyjrzyjmy się więc jej bliżej. Została przedstawiona przez Jeana Meeusa w 1991 roku. W książce, swojego autorstwa “Astronomical Algorithms”, zawarł sposób na wyliczenie daty Niedzieli Wielkanocnej. Uwzględnił zarówno algorytm dla kalendarza gregoriańskiego, jak i juliańskiego.

Metody opisane przez Meeusa są uniwersalne. Nie wymagają od nas żadnych założeń czy wyjątków. Jednakże, jak się przekonacie, wymagają więcej obliczeń.

Dla każdego kalendarza w pierwszej kolejności opiszemy poszczególne kroki metody. Następnie zaproponujemy przykładowy program w języku Ruby.

Algorytm dla kalendarza gregoriańskiego

Nasz algorytm polega na wyliczeniu pewnej grupy wartości: a, b, c, d, e, f, g, h, i, k, l, m, p. Z ich pomocą wyznaczymy dzień i miesiąc święta.

Jak policzyć potrzebne wielkości? Poniżej mała pomoc:

Wybierzmy rok dla którego chcemy poznać datę. 😉

  1. Rok należy podzielić przez 19. W wyniku tego działania otrzymamy resztę, która jest naszą wartością a.
  2. Następnie rok dzielimy przez 100. Zaokrąglony w dół wynik to nasze b, a reszta w tego dzielenia to poszukiwane c.
  3. Otrzymane b dzielimy przez 4. Po zaokrągleniu wyniku w dół otrzymujemy d, a resztę w tego dzielenia nazywamy e.
  4. Teraz wykonajmy działanie (b + 8) / 25. Jego wynik zaokrąglamy w dół i dostajemy f.
  5. Kolejnym krokiem będzie policzenie (b – f + 1) / 3. Zaokrąglając wynik w dół otrzymamy g.
  6. Szóstym krokiem będzie działanie (19 * a + b – d – g + 15) % 30. Otrzymany wynik nazywamy h.
  7. Kolejne wielkości otrzymujemy dzieląc c przez 4. Zaokrąglony w dół wynik to nasze i, a reszta to nasze k.
  8. Teraz wykonujemy działanie (32 + 2 * e + 2 * i – h – k) % 7. Uzyskany rezultat to l.
  9. Zaokrąglając w dół wynik z (a + 11 * h + 22 * l) / 451 dostaniemy m.
  10. Ostatnią naszą wielkość p otrzymujemy z dzielenia modulo (h + l – 7 * m + 114) % 31.

Nie pozostaje nam nic innego jak policzyć odpowiednio:

  • Dzień Wielkanocy = p + 1.
  • Miesiąc = zaokrąglony w dół wynik z dzielenia (h + l – 7 * m + 114) przez 31.

Program w Ruby może wyglądać:

require 'date'

def gregorian_easter_date(year)
  a = year % 19
  b = (year / 100).floor
  c = year % 100
  d = (b / 4).floor
  e = b % 4
  f = ((b + 8) / 25).floor
  g = ((b - f + 1) / 3).floor
  h = (19 * a + b - d - g + 15) % 30
  i = (c / 4).floor
  k = c % 4
  l = (32 + 2 * e + 2 * i - h - k) % 7
  m = ((a + 11 * h + 22 * l) / 451).floor
  q = (h + l - 7 * m + 114)
  day = q % 31 + 1
  month = (q / 31).floor
  Date.new(year, month, day)
end

Jak działa powyższa metoda? Przekonajmy się i wyliczmy kilka dat.

3.1.0 :020 > gregorian_easter_date(2022)
 => #<Date: 2022-04-17 ((2459687j,0s,0n),+0s,2299161j)>
3.1.0 :021 > gregorian_easter_date(2021)
 => #<Date: 2021-04-04 ((2459309j,0s,0n),+0s,2299161j)>
3.1.0 :022 > gregorian_easter_date(2023)
 => #<Date: 2023-04-09 ((2460044j,0s,0n),+0s,2299161j)>
3.1.0 :023 > gregorian_easter_date(1900)
 => #<Date: 1900-04-15 ((2415125j,0s,0n),+0s,2299161j)>
3.1.0 :024 > gregorian_easter_date(1967)
 => #<Date: 1967-03-26 ((2439576j,0s,0n),+0s,2299161j)>

Daty te łatwo będziemy mogli sprawdzić.

Algorytm dla kalendarza juliańskiego

Ten algorytm jest zdecydowanie krótszy. Wyliczamy tylko pięć wielkości: a, b, c, d, e za pomocą, których wyznaczymy dzień i miesiąc. Szczegóły poniżej:

  1. Rok dzielimy przez 4. Otrzymaną resztę nazywamy a.
  2. Wartość b otrzymujemy jako resztę z dzielenia roku przez 7.
  3. Dzieląc rok przez 19 dostaniemy resztę, którą oznaczamy jako c.
  4. Następnie wykonajmy działanie (19 * c + 15) % 30. Nasze d to wynik z tego dzielenia.
  5. Wyznaczamy e jako iloraz z (2 * a + 4 * b – d + 34) % 7.

Teraz już możemy policzyć:

  • Dzień = rezultat z (d + e + 114) % 31, a następnie dodajemy 1
  • Miesiąc = zaokrąglony wynik w dół z (d + e + 114) / 31.
require 'date'

def julian_easter_date(year)
  a = year % 4
  b = year % 7
  c = year % 19
  d = (19 * c + 15) % 30
  e = (2 * a + 4 * b - d + 34) % 7
  day = (d + e + 114) % 31 + 1
  month = ((d + e + 114) / 31).floor
  Date.new(year, month, day)
end

Jako ciekawostka! Kalendarz juliański obowiązuje w Kościele Prawosławnym. Znając już datę świąt w obrządku prawosławnym możemy dowiedzieć się na jaki dzień i miesiąc kalendarza gregoriańskiego przypada uroczystość. Wystarczy, do uzyskanego wyniku, dodać 13. Zasada ta działa tylko dla lat 1900 - 2100.

Wyniki przedstawiają się następująco:

3.1.0 :035 > julian_easter_date(2022)
 => #<Date: 2022-04-11 ((2459681j,0s,0n),+0s,2299161j)>
3.1.0 :036 > julian_easter_date(2021)
 => #<Date: 2021-04-19 ((2459324j,0s,0n),+0s,2299161j)>
3.1.0 :037 > julian_easter_date(2023)
 => #<Date: 2023-04-03 ((2460038j,0s,0n),+0s,2299161j)>
3.1.0 :038 > julian_easter_date(1900)
 => #<Date: 1900-04-09 ((2415119j,0s,0n),+0s,2299161j)>
3.1.0 :039 > julian_easter_date(1967)
 => #<Date: 1967-04-17 ((2439598j,0s,0n),+0s,2299161j)>

Życzymy Wam miłej zabawy z programowaniem.

🐏 🐰 🐇 🥚 🐤 🐣 🐥

Kategorie: ,

Ostatnia aktualizacja:

Zostaw komentarz