mirror of
https://github.com/InsanusMokrassar/krontab.git
synced 2024-11-22 16:23:55 +00:00
add CronDateTime related to klock
This commit is contained in:
parent
f3c4747053
commit
ba58d016b6
@ -31,6 +31,8 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$kotlin_coroutines_version"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$kotlin_coroutines_version"
|
||||||
|
|
||||||
|
implementation "com.soywiz.korlibs.klock:klock:$klockVersion"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jvm8Main {
|
jvm8Main {
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
kotlin_version=1.3.31
|
kotlin_version=1.3.50
|
||||||
kotlin_coroutines_version=1.2.1
|
kotlin_coroutines_version=1.3.2
|
||||||
|
|
||||||
gradle_bintray_plugin_version=1.8.4
|
gradle_bintray_plugin_version=1.8.4
|
||||||
|
|
||||||
|
klockVersion=1.7.3
|
||||||
|
|
||||||
project_public_name=Krontab
|
project_public_name=Krontab
|
||||||
project_public_description=It is analog of crontab util for Kotlin Coroutines
|
project_public_description=It is analog of crontab util for Kotlin Coroutines
|
||||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip
|
||||||
|
@ -16,3 +16,5 @@ include 'services:webservice'
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
rootProject.name = 'krontab'
|
rootProject.name = 'krontab'
|
||||||
|
|
||||||
|
enableFeaturePreview('GRADLE_METADATA')
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.github.insanusmokrassar.krontab.parts
|
||||||
|
|
||||||
|
import com.soywiz.klock.*
|
||||||
|
|
||||||
|
data class CronDateTime(
|
||||||
|
val month: Byte? = null,
|
||||||
|
val dayOfMonth: Byte? = null,
|
||||||
|
val hour: Byte? = null,
|
||||||
|
val minute: Byte? = null,
|
||||||
|
val second: Byte? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
fun CronDateTime.toNearDateTime(relativelyTo: DateTime = DateTime.now()): DateTime {
|
||||||
|
var current = relativelyTo
|
||||||
|
|
||||||
|
second ?.let {
|
||||||
|
val left = it - current.seconds
|
||||||
|
current += DateTimeSpan(minutes = if (left < 0) 1 else 0, seconds = left)
|
||||||
|
}
|
||||||
|
|
||||||
|
minute ?.let {
|
||||||
|
val left = it - current.minutes
|
||||||
|
current += DateTimeSpan(hours = if (left < 0) 1 else 0, minutes = left)
|
||||||
|
}
|
||||||
|
|
||||||
|
hour ?.let {
|
||||||
|
val left = it - current.hours
|
||||||
|
current += DateTimeSpan(days = if (left < 0) 1 else 0, hours = left)
|
||||||
|
}
|
||||||
|
|
||||||
|
dayOfMonth ?.let {
|
||||||
|
val left = it - current.dayOfMonth
|
||||||
|
current += DateTimeSpan(months = if (left < 0) 1 else 0, days = left)
|
||||||
|
}
|
||||||
|
|
||||||
|
month ?.let {
|
||||||
|
val left = it - current.month0
|
||||||
|
current += DateTimeSpan(months = if (left < 0) 1 else 0, days = left)
|
||||||
|
}
|
||||||
|
|
||||||
|
return current
|
||||||
|
}
|
@ -1,110 +0,0 @@
|
|||||||
package com.github.insanusmokrassar.krontab.parts
|
|
||||||
|
|
||||||
import kotlin.math.floor
|
|
||||||
|
|
||||||
private const val millisCount = 1000
|
|
||||||
private const val secondsCount = 60
|
|
||||||
private const val minutesCount = 60
|
|
||||||
private const val hoursCount = 24
|
|
||||||
private const val weekDaysCount = 7
|
|
||||||
|
|
||||||
private const val secondsK = 1000
|
|
||||||
private const val minutesK = 60 * secondsK
|
|
||||||
private const val hoursK = 60 * minutesK
|
|
||||||
private const val daysK = 24 * hoursK
|
|
||||||
private const val weekDaysK = 7 * daysK
|
|
||||||
|
|
||||||
private fun <T> List<T>.notMaxOrNull(max: Int): List<T>? = if (size >= max) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
this
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun KronTimes(
|
|
||||||
timePattern: TimePattern
|
|
||||||
): List<KronTime> {
|
|
||||||
val reversedParts = timePattern.split(" ").toMutableList().also {
|
|
||||||
it.reverse()
|
|
||||||
}
|
|
||||||
val weekDaysParts = getTimes(reversedParts.removeAt(0), 0, weekDaysCount).notMaxOrNull(weekDaysCount) ?.map {
|
|
||||||
it.toByte()
|
|
||||||
}
|
|
||||||
val hoursParts = getTimes(reversedParts.removeAt(0), 0, hoursCount).let {
|
|
||||||
(weekDaysParts ?.let { _ ->
|
|
||||||
it
|
|
||||||
} ?: it.notMaxOrNull(hoursCount)) ?.map {
|
|
||||||
it.toByte()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val minutesParts = getTimes(reversedParts.removeAt(0), 0, minutesCount).let {
|
|
||||||
(hoursParts ?.let { _ ->
|
|
||||||
it
|
|
||||||
} ?: it.notMaxOrNull(minutesCount)) ?.map {
|
|
||||||
it.toByte()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val secondsParts = getTimes(reversedParts.removeAt(0), 0, secondsCount).let {
|
|
||||||
(minutesParts ?.let { _ ->
|
|
||||||
it
|
|
||||||
} ?: it.notMaxOrNull(secondsCount)) ?.map {
|
|
||||||
it.toByte()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val millisParts = if (reversedParts.isNotEmpty()) {
|
|
||||||
getTimes(reversedParts.removeAt(0), 0, millisCount).let {
|
|
||||||
secondsParts ?.let { _ ->
|
|
||||||
it
|
|
||||||
} ?: it.notMaxOrNull(millisCount)
|
|
||||||
} ?.map {
|
|
||||||
it.toShort()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
return millisParts ?.flatMap { millis ->
|
|
||||||
secondsParts ?.flatMap { seconds ->
|
|
||||||
minutesParts ?.flatMap { minutes ->
|
|
||||||
hoursParts ?.flatMap { hours ->
|
|
||||||
weekDaysParts ?.map { weekDay ->
|
|
||||||
KronTime(millis, seconds, minutes, hours, weekDay)
|
|
||||||
} ?: listOf(KronTime(millis, seconds, minutes, hours))
|
|
||||||
} ?: listOf(KronTime(millis, seconds, minutes))
|
|
||||||
} ?: listOf(KronTime(millis, seconds))
|
|
||||||
} ?: listOf(KronTime(milliseconds = millis))
|
|
||||||
} ?: listOf(KronTime())
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun KronTime(
|
|
||||||
fullMillis: Milliseconds
|
|
||||||
): KronTime {
|
|
||||||
val millis = (fullMillis % millisCount).toShort()
|
|
||||||
var currentDivided: Double = floor(fullMillis.toDouble() / millisCount)
|
|
||||||
|
|
||||||
val seconds: Byte = (currentDivided % secondsCount).toByte()
|
|
||||||
currentDivided = floor(currentDivided / secondsCount)
|
|
||||||
|
|
||||||
val minutes: Byte = (currentDivided % minutesCount).toByte()
|
|
||||||
currentDivided = floor(currentDivided / minutesCount)
|
|
||||||
|
|
||||||
val hours: Byte = (currentDivided % hoursCount).toByte()
|
|
||||||
currentDivided = floor(currentDivided / hoursCount)
|
|
||||||
|
|
||||||
val days: Byte = (currentDivided % weekDaysCount).toByte()
|
|
||||||
|
|
||||||
return KronTime(
|
|
||||||
millis,
|
|
||||||
seconds,
|
|
||||||
minutes,
|
|
||||||
hours,
|
|
||||||
days
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal data class KronTime(
|
|
||||||
val milliseconds: Milliseconds? = null,
|
|
||||||
val seconds: Seconds? = null,
|
|
||||||
val minutes: Minutes? = null,
|
|
||||||
val hours: Hours? = null,
|
|
||||||
val weekDays: WeekDays? = null
|
|
||||||
)
|
|
@ -1,93 +0,0 @@
|
|||||||
package com.github.insanusmokrassar.krontab.parts
|
|
||||||
|
|
||||||
internal inline fun buildPeriodRegex(periodNumbers: Int): Regex {
|
|
||||||
val periodRegex = "\\d{1,$periodNumbers}"
|
|
||||||
return Regex("(\\*(/$periodRegex)?)|($periodRegex(-$periodRegex)?)")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun extractLongTermPeriod(period: String, minPeriodValue: Int, maxPeriodValue: Int): List<Int>? {
|
|
||||||
if (period.contains("-")) {
|
|
||||||
val (first, second) = period.split("-")
|
|
||||||
val firstNumber = first.toInt().let {
|
|
||||||
if (it < minPeriodValue) {
|
|
||||||
minPeriodValue
|
|
||||||
} else {
|
|
||||||
it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val secondNumber = second.toInt().let {
|
|
||||||
if (it > maxPeriodValue) {
|
|
||||||
maxPeriodValue
|
|
||||||
} else {
|
|
||||||
it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (firstNumber .. secondNumber).toList()
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun extractPeriods(period: String, minPeriodValue: Int, maxPeriodValue: Int): List<Int>? {
|
|
||||||
if (period.startsWith("*")) {
|
|
||||||
val splitted = period.split("/")
|
|
||||||
when {
|
|
||||||
splitted.size > 1 -> {
|
|
||||||
val repeatPeriod = splitted[1].toInt()
|
|
||||||
return (minPeriodValue .. maxPeriodValue step repeatPeriod).toList()
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
(minPeriodValue .. maxPeriodValue).toList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private val oneTimeRegex = Regex("^\\d*$")
|
|
||||||
private fun extractOneTime(period: String, minPeriodValue: Int, maxPeriodValue: Int): List<Int>? {
|
|
||||||
oneTimeRegex.find(period) ?.let {
|
|
||||||
val found = it.groupValues.firstOrNull() ?: return null
|
|
||||||
val foundAsInt = found.toInt()
|
|
||||||
val resultTime = when {
|
|
||||||
minPeriodValue > foundAsInt -> minPeriodValue
|
|
||||||
maxPeriodValue < foundAsInt -> maxPeriodValue
|
|
||||||
else -> foundAsInt
|
|
||||||
}
|
|
||||||
return listOf(resultTime)
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun adaptPeriod(period: String, minPeriodValue: Int, maxPeriodValue: Int): List<Int> {
|
|
||||||
return extractLongTermPeriod(
|
|
||||||
period,
|
|
||||||
minPeriodValue,
|
|
||||||
maxPeriodValue
|
|
||||||
) ?: extractPeriods(
|
|
||||||
period,
|
|
||||||
minPeriodValue,
|
|
||||||
maxPeriodValue
|
|
||||||
) ?: extractOneTime(
|
|
||||||
period,
|
|
||||||
minPeriodValue,
|
|
||||||
maxPeriodValue
|
|
||||||
) ?: emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun getTimes(
|
|
||||||
period: String,
|
|
||||||
minPeriodValue: Int,
|
|
||||||
maxPeriodValue: Int,
|
|
||||||
unconfinedVariants: Map<String, Int> = emptyMap()
|
|
||||||
): List<Int> {
|
|
||||||
return period.split(",").flatMap {
|
|
||||||
unconfinedVariants[it] ?.let {
|
|
||||||
listOf(it)
|
|
||||||
} ?: adaptPeriod(
|
|
||||||
it,
|
|
||||||
minPeriodValue,
|
|
||||||
maxPeriodValue
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
package com.github.insanusmokrassar.krontab.parts
|
|
||||||
|
|
||||||
internal typealias Milliseconds = Short
|
|
||||||
internal typealias Seconds = Byte
|
|
||||||
internal typealias Minutes = Byte
|
|
||||||
internal typealias Hours = Byte
|
|
||||||
internal typealias WeekDays = Byte
|
|
||||||
internal typealias Weeks = Byte
|
|
||||||
|
|
||||||
typealias TimePattern = String
|
|
||||||
typealias TimeSubPattern = String
|
|
Loading…
Reference in New Issue
Block a user