diff --git a/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/eastersunday/EasterDateCalculator.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/eastersunday/EasterDateCalculator.java new file mode 100644 index 0000000000..a9c066ebc4 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/eastersunday/EasterDateCalculator.java @@ -0,0 +1,76 @@ +package com.baeldung.algorithms.eastersunday; + +import java.time.LocalDate; + +public class EasterDateCalculator { + + LocalDate computeEasterDateWithGaussAlgorithm(int year) { + int a = year % 19; + int b = year % 4; + int c = year % 7; + int k = year / 100; + int p = (13 + 8*k) / 25; + int q = k / 4; + int M = (15 - p + k - q) % 30; + int N = (4 + k - q) % 7; + int d = (19*a + M) % 30; + int e = (2*b + 4*c + 6*d + N) % 7; + + if (d==29 && e == 6) { + return LocalDate.of(year, 4, 19); + } else if (d==28 && e==6 && ((11*M + 11)%30 < 10)) { + return LocalDate.of(year, 4, 18); + } + + int H = 22 + d + e; + if (H <= 31) { + return LocalDate.of(year, 3, H); + } + return LocalDate.of(year, 4, H-31); + } + + LocalDate computeEasterDateWithButcherMeeusAlgorithm(int year) { + int a = year % 19; + int b = year / 100; + int c = year % 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 = (2*e + 2*i - h - k + 32) % 7; + int m = (a + 11*h + 22*l) / 451; + int t = h + l - 7*m + 114; + int n = t / 31; + int o = t % 31; + return LocalDate.of(year, n, o+1); + } + + LocalDate computeEasterDateWithConwayAlgorithm(int year) { + int s = year / 100; + int t = year % 100; + int a = t / 4; + int p = s % 4; + int x = (9 - 2*p) % 7; + int y = (x + t + a) % 7; + int g = year % 19; + int G = g + 1; + int b = s / 4; + int r = 8 * (s + 11) / 25; + int C = -s + b + r; + int d = (11*G + C) % 30; + d = (d + 30) % 30; + int h = (551 - 19*d + G) / 544; + int e = (50 - d - h) % 7; + int f = (e + y) % 7; + int R = 57 - d - f - h; + + if (R <= 31) { + return LocalDate.of(year, 3, R); + } + return LocalDate.of(year, 4, R-31); + } + +} diff --git a/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/eastersunday/EasterDateCalculatorUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/eastersunday/EasterDateCalculatorUnitTest.java new file mode 100644 index 0000000000..f92bd4b312 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/eastersunday/EasterDateCalculatorUnitTest.java @@ -0,0 +1,53 @@ +package com.baeldung.algorithms.eastersunday; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.time.LocalDate; + +import org.junit.jupiter.api.Test; + +public class EasterDateCalculatorUnitTest { + + @Test + void givenEasterInMarch_whenComputeEasterDateWithGaussAlgorithm_thenCorrectResult() { + assertEquals(LocalDate.of(2024, 3, 31), new EasterDateCalculator().computeEasterDateWithGaussAlgorithm(2024)); + } + + @Test + void givenEasterInApril_whenComputeEasterDateWithGaussAlgorithm_thenCorrectResult() { + assertEquals(LocalDate.of(2004, 4, 11), new EasterDateCalculator().computeEasterDateWithGaussAlgorithm(2004)); + } + + @Test + void givenEdgeCases_whenComputeEasterDateWithGaussAlgorithm_thenCorrectResult() { + assertEquals(LocalDate.of(1981, 4, 19), new EasterDateCalculator().computeEasterDateWithGaussAlgorithm(1981)); + assertEquals(LocalDate.of(1954, 4, 18), new EasterDateCalculator().computeEasterDateWithGaussAlgorithm(1954)); + } + + @Test + void givenEasterInMarch_whenComputeEasterDateWithButcherMeeusAlgorithm_thenCorrectResult() { + assertEquals(LocalDate.of(2024, 3, 31), new EasterDateCalculator().computeEasterDateWithButcherMeeusAlgorithm(2024)); + } + + @Test + void givenEasterInApril_whenComputeEasterDateWithButcherMeeusAlgorithm_thenCorrectResult() { + assertEquals(LocalDate.of(2004, 4, 11), new EasterDateCalculator().computeEasterDateWithButcherMeeusAlgorithm(2004)); + // The following are added just to notice that there is no need for a special case with this algorithm + assertEquals(LocalDate.of(1981, 4, 19), new EasterDateCalculator().computeEasterDateWithGaussAlgorithm(1981)); + assertEquals(LocalDate.of(1954, 4, 18), new EasterDateCalculator().computeEasterDateWithGaussAlgorithm(1954)); + } + + @Test + void givenEasterInMarch_whenComputeEasterDateWithConwayAlgorithm_thenCorrectResult() { + assertEquals(LocalDate.of(2024, 3, 31), new EasterDateCalculator().computeEasterDateWithConwayAlgorithm(2024)); + } + + @Test + void givenEasterInApril_whenComputeEasterDateWithConwayAlgorithm_thenCorrectResult() { + assertEquals(LocalDate.of(2004, 4, 11), new EasterDateCalculator().computeEasterDateWithConwayAlgorithm(2004)); + // The following are added just to notice that there is no need for a special case with this algorithm + assertEquals(LocalDate.of(1981, 4, 19), new EasterDateCalculator().computeEasterDateWithGaussAlgorithm(1981)); + assertEquals(LocalDate.of(1954, 4, 18), new EasterDateCalculator().computeEasterDateWithGaussAlgorithm(1954)); + } + +}