diff --git a/src/main/kotlin/org/javafreedom/khol/BaseCalculationAlgorithm.kt b/src/main/kotlin/org/javafreedom/khol/BaseCalculationAlgorithm.kt new file mode 100644 index 0000000..9801aa0 --- /dev/null +++ b/src/main/kotlin/org/javafreedom/khol/BaseCalculationAlgorithm.kt @@ -0,0 +1,9 @@ +package org.javafreedom.khol + +import kotlinx.datetime.LocalDate + +fun interface BaseCalculationAlgorithm { + + fun calculateBaseDate(year: Int): LocalDate + +} diff --git a/src/main/kotlin/org/javafreedom/khol/Declaration.kt b/src/main/kotlin/org/javafreedom/khol/Declaration.kt index 25adeb3..48577e7 100644 --- a/src/main/kotlin/org/javafreedom/khol/Declaration.kt +++ b/src/main/kotlin/org/javafreedom/khol/Declaration.kt @@ -3,6 +3,8 @@ package org.javafreedom.khol import kotlinx.datetime.DateTimeUnit import kotlinx.datetime.LocalDate import kotlinx.datetime.plus +import org.javafreedom.khol.algorithm.FirstAdvent +import org.javafreedom.khol.algorithm.GregorianEasterSundayGauss sealed class Declaration(open val name: String, open val validFromYear: Int, @@ -28,8 +30,10 @@ sealed class Declaration(open val name: String, override val validIn: Set = emptySet() ) : Declaration(name, validFromYear, validIn) { + private val gregorianEasterSundayAlgorithm = GregorianEasterSundayGauss() + override fun concreteForYear(year: Int): LocalDate { - val value = HolidayCalculusUtil.gregorianEasterSunday(year).plus(this.offset, DateTimeUnit.DAY) + val value = gregorianEasterSundayAlgorithm.calculateBaseDate(year).plus(this.offset, DateTimeUnit.DAY) return LocalDate(year, value.month, value.dayOfMonth) } } @@ -41,8 +45,10 @@ sealed class Declaration(open val name: String, override val validIn: Set = emptySet() ) : Declaration(name, validFromYear, validIn) { + private val firstAdventAlgorithm = FirstAdvent() + override fun concreteForYear(year: Int): LocalDate { - val value = HolidayCalculusUtil.firstAdvent(year).plus(this.offset, DateTimeUnit.DAY) + val value = firstAdventAlgorithm.calculateBaseDate(year).plus(this.offset, DateTimeUnit.DAY) return LocalDate(year, value.month, value.dayOfMonth) } } diff --git a/src/main/kotlin/org/javafreedom/khol/algorithm/FirstAdvent.kt b/src/main/kotlin/org/javafreedom/khol/algorithm/FirstAdvent.kt new file mode 100644 index 0000000..332b021 --- /dev/null +++ b/src/main/kotlin/org/javafreedom/khol/algorithm/FirstAdvent.kt @@ -0,0 +1,23 @@ +@file:Suppress("detekt:style:MagicNumber") +package org.javafreedom.khol.algorithm + +import kotlinx.datetime.DayOfWeek +import kotlinx.datetime.DateTimeUnit +import kotlinx.datetime.LocalDate +import kotlinx.datetime.plus +import org.javafreedom.khol.BaseCalculationAlgorithm + +class FirstAdvent : BaseCalculationAlgorithm { + + override fun calculateBaseDate(year: Int): LocalDate { + // Find November 30th of the given year + val november30 = LocalDate(year, 11, 30) + // Get the day of the week for November 30th + val dayOfWeek = november30.dayOfWeek + // Calculate how many days to add to get to the nearest Sunday (Advent starts) + val daysToSunday = (DayOfWeek.SUNDAY.value - dayOfWeek.value + 7) % 7 + // The first Advent Sunday is the Sunday closest to or on November 30th + return november30.plus(daysToSunday, DateTimeUnit.DAY) + } + +} diff --git a/src/main/kotlin/org/javafreedom/khol/HolidayCalculusUtil.kt b/src/main/kotlin/org/javafreedom/khol/algorithm/GregorianEasterSundayGauss.kt similarity index 71% rename from src/main/kotlin/org/javafreedom/khol/HolidayCalculusUtil.kt rename to src/main/kotlin/org/javafreedom/khol/algorithm/GregorianEasterSundayGauss.kt index c56e641..cf63e4f 100644 --- a/src/main/kotlin/org/javafreedom/khol/HolidayCalculusUtil.kt +++ b/src/main/kotlin/org/javafreedom/khol/algorithm/GregorianEasterSundayGauss.kt @@ -1,17 +1,12 @@ @file:Suppress("detekt:style:MagicNumber") +package org.javafreedom.khol.algorithm -package org.javafreedom.khol - -import kotlinx.datetime.DateTimeUnit -import kotlinx.datetime.DayOfWeek import kotlinx.datetime.LocalDate -import kotlinx.datetime.plus +import org.javafreedom.khol.BaseCalculationAlgorithm + +class GregorianEasterSundayGauss : BaseCalculationAlgorithm { -object HolidayCalculusUtil { - /** - * Computus algoritym - */ - fun gregorianEasterSunday(year: Int) : LocalDate { + override fun calculateBaseDate(year: Int): LocalDate { // Golden number (position of the year in the 19-year Metonic cycle) val goldenNumber = year % 19 @@ -61,14 +56,4 @@ object HolidayCalculusUtil { return LocalDate(year, month, day) } - fun firstAdvent(year: Int): LocalDate { - // Find November 30th of the given year - val november30 = LocalDate(year, 11, 30) - // Get the day of the week for November 30th - val dayOfWeek = november30.dayOfWeek - // Calculate how many days to add to get to the nearest Sunday (Advent starts) - val daysToSunday = (DayOfWeek.SUNDAY.value - dayOfWeek.value + 7) % 7 - // The first Advent Sunday is the Sunday closest to or on November 30th - return november30.plus(daysToSunday, DateTimeUnit.DAY) - } } diff --git a/src/test/kotlin/org/javafreedom/khol/algorithm/FirstAdventTest.kt b/src/test/kotlin/org/javafreedom/khol/algorithm/FirstAdventTest.kt new file mode 100644 index 0000000..4ac164b --- /dev/null +++ b/src/test/kotlin/org/javafreedom/khol/algorithm/FirstAdventTest.kt @@ -0,0 +1,24 @@ +package org.javafreedom.khol.algorithm + +import kotlinx.datetime.number +import kotlin.test.Test +import kotlin.test.assertEquals + +class FirstAdventTest { + + private val firstAdvent = FirstAdvent() + + @Test + fun testFirstAdvent() { + val result0 = firstAdvent.calculateBaseDate(2024) + assertEquals(2024, result0.year) + assertEquals(12, result0.month.number) + assertEquals(1, result0.dayOfMonth) + + val result1 = firstAdvent.calculateBaseDate(2023) + assertEquals(2023, result1.year) + assertEquals(12, result1.month.number) + assertEquals(3, result1.dayOfMonth) + } + +} diff --git a/src/test/kotlin/org/javafreedom/khol/HolidayCalculusUtilTest.kt b/src/test/kotlin/org/javafreedom/khol/algorithm/GregorianEasterSundayGaussTest.kt similarity index 50% rename from src/test/kotlin/org/javafreedom/khol/HolidayCalculusUtilTest.kt rename to src/test/kotlin/org/javafreedom/khol/algorithm/GregorianEasterSundayGaussTest.kt index 9d71075..2079572 100644 --- a/src/test/kotlin/org/javafreedom/khol/HolidayCalculusUtilTest.kt +++ b/src/test/kotlin/org/javafreedom/khol/algorithm/GregorianEasterSundayGaussTest.kt @@ -1,14 +1,12 @@ -package org.javafreedom.khol +package org.javafreedom.khol.algorithm import kotlinx.datetime.number -import org.javafreedom.khol.HolidayCalculusUtil.firstAdvent -import org.javafreedom.khol.HolidayCalculusUtil.gregorianEasterSunday import kotlin.test.Test import kotlin.test.assertEquals private data class EasterCalculusArguments(val year: Int, val month: Int, val day: Int) -class HolidayCalculusUtilTest { +class GregorianEasterSundayGaussTest { private val argumentsList = mutableListOf( EasterCalculusArguments(2008, 3, 23), @@ -16,29 +14,19 @@ class HolidayCalculusUtilTest { EasterCalculusArguments(2017, 4, 16), EasterCalculusArguments(2018, 4, 1), EasterCalculusArguments(2019, 4, 21), - EasterCalculusArguments(2027, 3, 28)) + EasterCalculusArguments(2027, 3, 28) + ) + + private val sut = GregorianEasterSundayGauss() @Test fun testEasterSunday() { argumentsList.forEach { - val result = gregorianEasterSunday(it.year) + val result = sut.calculateBaseDate(it.year) assertEquals(it.year, result.year) assertEquals(it.month, result.month.number) assertEquals(it.day, result.dayOfMonth) } } - @Test - fun testFirstAdvent() { - val result0 = firstAdvent(2024) - assertEquals(2024, result0.year) - assertEquals(12, result0.month.number) - assertEquals(1, result0.dayOfMonth) - - val result1 = firstAdvent(2023) - assertEquals(2023, result1.year) - assertEquals(12, result1.month.number) - assertEquals(3, result1.dayOfMonth) - } - }