diff --git a/src/commonMain/kotlin/dev/inmo/krontab/internal/CronDateTime.kt b/src/commonMain/kotlin/dev/inmo/krontab/internal/CronDateTime.kt index 802e765..2200a06 100644 --- a/src/commonMain/kotlin/dev/inmo/krontab/internal/CronDateTime.kt +++ b/src/commonMain/kotlin/dev/inmo/krontab/internal/CronDateTime.kt @@ -2,6 +2,7 @@ package dev.inmo.krontab.internal import com.soywiz.klock.* import dev.inmo.krontab.KronScheduler +import dev.inmo.krontab.utils.copy /** * @param daysOfWeek 0-6 @@ -32,14 +33,14 @@ internal data class CronDateTime( } internal val calculators = listOf( + years ?.let { NearDateTimeCalculatorYears(it) }, + daysOfWeek ?.let { NearDateTimeCalculatorWeekDays(it) }, NearDateTimeCalculatorMillis(arrayOf(0)), seconds ?.let { NearDateTimeCalculatorSeconds(it) }, minutes ?.let { NearDateTimeCalculatorMinutes(it) }, hours ?.let { NearDateTimeCalculatorHours(it) }, daysOfMonth ?.let { NearDateTimeCalculatorDays(it) }, months ?.let { NearDateTimeCalculatorMonths(it) }, - years ?.let { NearDateTimeCalculatorYears(it) }, - daysOfWeek ?.let { NearDateTimeCalculatorWeekDays(it) }, ) internal fun toNearDateTime(relativelyTo: DateTime = DateTime.now()): DateTime? { diff --git a/src/commonMain/kotlin/dev/inmo/krontab/internal/NearDateTimeCalculator.kt b/src/commonMain/kotlin/dev/inmo/krontab/internal/NearDateTimeCalculator.kt index 7992ab4..7983935 100644 --- a/src/commonMain/kotlin/dev/inmo/krontab/internal/NearDateTimeCalculator.kt +++ b/src/commonMain/kotlin/dev/inmo/krontab/internal/NearDateTimeCalculator.kt @@ -4,17 +4,27 @@ import com.soywiz.klock.* import dev.inmo.krontab.utils.copy import kotlin.math.min -internal class NearDateTimeCalculator( - private val times: Array, - private val partGetter: (DateTime) -> T, - private val partSetter: (DateTime, T) -> DateTime? -) where T : Comparable, T : Number { +fun interface NearDateTimeCalculator { /** * @return pair of near [DateTime] for this checker and [Boolean] flag that all previous calculations must be * recalculated */ fun calculateNearTime( relativelyTo: DateTime + ): Pair? +} + +internal class CommonNearDateTimeCalculator( + private val times: Array, + private val partGetter: (DateTime) -> T, + private val partSetter: (DateTime, T) -> DateTime? +) : NearDateTimeCalculator where T : Comparable, T : Number { + /** + * @return pair of near [DateTime] for this checker and [Boolean] flag that all previous calculations must be + * recalculated + */ + override fun calculateNearTime( + relativelyTo: DateTime ): Pair? { val currentData = partGetter(relativelyTo) val greaterOrEquals = times.firstOrNull { it >= currentData } @@ -33,7 +43,7 @@ internal class NearDateTimeCalculator( internal fun NearDateTimeCalculatorMillis( times: Array -) = NearDateTimeCalculator( +) = CommonNearDateTimeCalculator( times, { it.milliseconds.toShort() }, { dateTime, newOne -> @@ -47,7 +57,7 @@ internal fun NearDateTimeCalculatorMillis( internal fun NearDateTimeCalculatorSeconds( times: Array -) = NearDateTimeCalculator( +) = CommonNearDateTimeCalculator( times, { it.seconds.toByte() }, { dateTime, newOne -> @@ -61,7 +71,7 @@ internal fun NearDateTimeCalculatorSeconds( internal fun NearDateTimeCalculatorMinutes( times: Array -) = NearDateTimeCalculator( +) = CommonNearDateTimeCalculator( times, { it.minutes.toByte() }, { dateTime, newOne -> @@ -75,7 +85,7 @@ internal fun NearDateTimeCalculatorMinutes( internal fun NearDateTimeCalculatorHours( times: Array -) = NearDateTimeCalculator( +) = CommonNearDateTimeCalculator( times, { it.hours.toByte() }, { dateTime, newOne -> @@ -89,7 +99,7 @@ internal fun NearDateTimeCalculatorHours( internal fun NearDateTimeCalculatorDays( times: Array -) = NearDateTimeCalculator( +) = CommonNearDateTimeCalculator( times, { it.dayOfMonth.toByte() }, { dateTime, newOne -> @@ -109,7 +119,7 @@ internal fun NearDateTimeCalculatorDays( internal fun NearDateTimeCalculatorMonths( times: Array -) = NearDateTimeCalculator( +) = CommonNearDateTimeCalculator( times, { it.dayOfMonth.toByte() }, { dateTime, newOne -> @@ -130,11 +140,12 @@ internal fun NearDateTimeCalculatorMonths( internal fun NearDateTimeCalculatorWeekDays( times: Array -) = NearDateTimeCalculator( +) = CommonNearDateTimeCalculator( times, { it.dayOfWeek.index0.toByte() }, { dateTime, newOne -> val currentDayOfWeek = dateTime.dayOfWeek.index0 + if (newOne.toInt() == currentDayOfWeek) return@CommonNearDateTimeCalculator dateTime (if (newOne < currentDayOfWeek) { dateTime.plus(7.days - (currentDayOfWeek - newOne).days) } else { @@ -150,11 +161,12 @@ internal fun NearDateTimeCalculatorWeekDays( internal fun NearDateTimeCalculatorYears( times: Array -) = NearDateTimeCalculator( +) = CommonNearDateTimeCalculator( times, { it.yearInt }, { dateTime, newOne -> val currentYear = dateTime.yearInt + if (newOne == currentYear) return@CommonNearDateTimeCalculator dateTime (if (newOne < currentYear) { null } else { diff --git a/src/commonTest/kotlin/dev/inmo/krontab/utils/StringParseTest.kt b/src/commonTest/kotlin/dev/inmo/krontab/utils/StringParseTest.kt index 0ddc638..7eae687 100644 --- a/src/commonTest/kotlin/dev/inmo/krontab/utils/StringParseTest.kt +++ b/src/commonTest/kotlin/dev/inmo/krontab/utils/StringParseTest.kt @@ -67,8 +67,8 @@ class StringParseTest { val flow = kronScheduler.asFlow() runTest { - val ranges = rangesEnds.map { it.first .. it.second }.flatten().toMutableList() - val expectedCollects = rangesEnds.sumOf { it.second - it.first + 1 } + val ranges = rangesEnds.map { it.first .. it.second }.flatten().distinct().toMutableList() + val expectedCollects = ranges.size var collected = 0 flow.takeWhile { ranges.isNotEmpty() }.collect {