diff --git a/CHANGELOG.md b/CHANGELOG.md index 753fe46..76f39ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,13 @@ ### 0.3.2 +* Add opportunity to use `first` shortcuts: + * Value property `TimeBuilder#first` for including via functions like `TimeBuilder#at` + * Shortcut for kron string format `f` or `F` +* Add opportunity to use `last` shortcuts: + * Value property `TimeBuilder#last` for including via functions like `TimeBuilder#at` + * Shortcut for kron string format `l` or `L` + ### 0.3.1 * Versions: diff --git a/src/commonMain/kotlin/com/insanusmokrassar/krontab/StringParser.kt b/src/commonMain/kotlin/com/insanusmokrassar/krontab/StringParser.kt index 24a53cd..01f5d5c 100644 --- a/src/commonMain/kotlin/com/insanusmokrassar/krontab/StringParser.kt +++ b/src/commonMain/kotlin/com/insanusmokrassar/krontab/StringParser.kt @@ -27,6 +27,8 @@ typealias KrontabTemplate = String * * {int}/{int} * * */{int} * * {int} + * * F + * * L * * Additional info about ranges can be found in follow accordance: * @@ -39,8 +41,9 @@ typealias KrontabTemplate = String * Examples: * * * "0/5 * * * *" for every five seconds triggering + * * "0/5,L * * * *" for every five seconds triggering and on 59 second * * "0/15 30 * * *" for every 15th seconds in a half of each hour - * * "1 2 3 4 5" for triggering in near first second of second minute of third hour of fourth day of may + * * "1 2 3 F,4,L 5" for triggering in near first second of second minute of third hour of fourth day of may * * @see com.insanusmokrassar.krontab.internal.createKronScheduler */ diff --git a/src/commonMain/kotlin/com/insanusmokrassar/krontab/builder/TimeBuilder.kt b/src/commonMain/kotlin/com/insanusmokrassar/krontab/builder/TimeBuilder.kt index d0653f4..75e87e2 100644 --- a/src/commonMain/kotlin/com/insanusmokrassar/krontab/builder/TimeBuilder.kt +++ b/src/commonMain/kotlin/com/insanusmokrassar/krontab/builder/TimeBuilder.kt @@ -12,6 +12,17 @@ sealed class TimeBuilder ( ) { private var result: Set? = null + /** + * The first possible value of builder + */ + val first + get() = restrictionsRange.first + /** + * The last possible value of builder. Using of this variable equal to using "L" in strings + */ + val last + get() = restrictionsRange.last + /** * After calling of this function this builder will allow any value of current time */ @@ -92,6 +103,15 @@ sealed class TimeBuilder ( @Suppress("MemberVisibilityCanBePrivate") infix operator fun rangeTo(endIncluding: Int) = (this from 0) rangeTo endIncluding + /** + * Will include the last possible value + */ + fun includeLast() = at(restrictionsRange.last) + /** + * Will include the first possible value + */ + fun includeFirst() = at(restrictionsRange.first) + internal fun build() = result ?.map { it.toByte() } ?.toTypedArray() } diff --git a/src/commonMain/kotlin/com/insanusmokrassar/krontab/internal/CronDateTime.kt b/src/commonMain/kotlin/com/insanusmokrassar/krontab/internal/CronDateTime.kt index bf173c8..e354b65 100644 --- a/src/commonMain/kotlin/com/insanusmokrassar/krontab/internal/CronDateTime.kt +++ b/src/commonMain/kotlin/com/insanusmokrassar/krontab/internal/CronDateTime.kt @@ -52,7 +52,13 @@ internal fun CronDateTime.toNearDateTime(relativelyTo: DateTime = DateTime.now() } klockDayOfMonth ?.let { - val left = it - current.dayOfMonth + val left = (it - current.dayOfMonth).let { diff -> + if (diff > 0 && current.endOfMonth.run { it > dayOfMonth && current.dayOfMonth == dayOfMonth }) { + 0 + } else { + diff + } + } current += DateTimeSpan(months = if (left < 0) 1 else 0, days = left) } diff --git a/src/commonMain/kotlin/com/insanusmokrassar/krontab/internal/Parser.kt b/src/commonMain/kotlin/com/insanusmokrassar/krontab/internal/Parser.kt index d3b9492..62b4b46 100644 --- a/src/commonMain/kotlin/com/insanusmokrassar/krontab/internal/Parser.kt +++ b/src/commonMain/kotlin/com/insanusmokrassar/krontab/internal/Parser.kt @@ -6,13 +6,18 @@ private fun createSimpleScheduler(from: String, dataRange: IntRange): Array { - val splitted = it.split("-") + currentToken.contains("-") -> { + val splitted = currentToken.split("-") (splitted.first().toInt().clamp(dataRange) .. splitted[1].toInt().clamp(dataRange)).toList() } - it.contains("/") -> { - val (start, step) = it.split("/") + currentToken.contains("/") -> { + val (start, step) = currentToken.split("/") val startNum = (if (start.isEmpty() || start == "*") { 0 } else {