Skip to content

Commit

Permalink
feat: refactor base day algorithms
Browse files Browse the repository at this point in the history
  • Loading branch information
triplem committed Dec 23, 2024
1 parent c34b18c commit dbda12b
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 43 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.javafreedom.khol

import kotlinx.datetime.LocalDate

interface BaseCalculationAlgorithm {

fun calculateBaseDate(year: Int): LocalDate

}
10 changes: 8 additions & 2 deletions src/main/kotlin/org/javafreedom/khol/Declaration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -28,8 +30,10 @@ sealed class Declaration(open val name: String,
override val validIn: Set<String> = 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)
}
}
Expand All @@ -41,8 +45,10 @@ sealed class Declaration(open val name: String,
override val validIn: Set<String> = 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)
}
}
Expand Down
22 changes: 22 additions & 0 deletions src/main/kotlin/org/javafreedom/khol/algorithm/FirstAdvent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
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)
}

}
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
@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

Expand Down Expand Up @@ -61,14 +55,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)
}
}
}
24 changes: 24 additions & 0 deletions src/test/kotlin/org/javafreedom/khol/algorithm/FirstAdventTest.kt
Original file line number Diff line number Diff line change
@@ -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)
}

}
Original file line number Diff line number Diff line change
@@ -1,44 +1,33 @@
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),
EasterCalculusArguments(2015, 4, 5),
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)
}

}
}

0 comments on commit dbda12b

Please sign in to comment.