Merge pull request #18 from InsanusMokrassar/0.6.1

0.6.1
This commit is contained in:
InsanusMokrassar 2021-06-03 13:40:06 +06:00 committed by GitHub
commit 5a6084c573
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 307 additions and 147 deletions

View File

@ -16,7 +16,7 @@ jobs:
- name: prebuild - name: prebuild
run: ./gradlew clean build run: ./gradlew clean build
- name: Publish package - name: Publish package
run: ./gradlew --no-parallel publishAllPublicationsToGithubPackagesRepository -x signJsPublication -x signJvmPublication -x signKotlinMultiplatformPublication -x signMetadataPublication -x signAndroidDebugPublication -x signAndroidReleasePublication run: ./gradlew --no-parallel publishAllPublicationsToGithubPackagesRepository -x signJsPublication -x signJvmPublication -x signKotlinMultiplatformPublication -x signMetadataPublication -x signAndroidReleasePublication
env: env:
GITHUBPACKAGES_USER: ${{ github.actor }} GITHUBPACKAGES_USER: ${{ github.actor }}
GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }} GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,5 +1,11 @@
# Changelog # Changelog
## 0.6.1
* Versions
* `Klock`: `2.1.0` -> `2.1.2`
* Rewriting of default mechanism of `KronScheduler`s
## 0.6.0 ## 0.6.0
* Versions * Versions

View File

@ -13,7 +13,7 @@ kotlin_coroutines_version=1.5.0
dokka_version=1.4.32 dokka_version=1.4.32
klockVersion=2.1.0 klockVersion=2.1.2
## Github reease ## Github reease
@ -33,6 +33,6 @@ androidx_work_version=2.5.0
## Common ## Common
version=0.6.0 version=0.6.1
android_code_version=4 android_code_version=5

View File

@ -16,13 +16,13 @@ fun Iterator<KronScheduler>.merge(): CollectionKronScheduler {
val collectionScheduler = CollectionKronScheduler() val collectionScheduler = CollectionKronScheduler()
forEach { forEach {
when (it) { when (it) {
is CronDateTimeScheduler -> cronDateTimes.addAll(it.cronDateTimes) is CronDateTimeScheduler -> cronDateTimes.add(it.cronDateTime)
is CronDateTimeSchedulerTz -> timezonedCronDateTimes.add(it) is CronDateTimeSchedulerTz -> timezonedCronDateTimes.add(it)
else -> collectionScheduler.include(it) else -> collectionScheduler.include(it)
} }
} }
if (cronDateTimes.isNotEmpty()) { if (cronDateTimes.isNotEmpty()) {
collectionScheduler.include(CronDateTimeScheduler(cronDateTimes)) collectionScheduler.include(CronDateTimeScheduler(cronDateTimes.merge()))
} }
if (timezonedCronDateTimes.isNotEmpty()) { if (timezonedCronDateTimes.isNotEmpty()) {
collectionScheduler.includeAll(mergeCronDateTimeSchedulers(timezonedCronDateTimes)) collectionScheduler.includeAll(mergeCronDateTimeSchedulers(timezonedCronDateTimes))

View File

@ -13,7 +13,7 @@ internal fun getAnyNext(relatively: DateTime) = anyCronDateTime.toNearDateTime(r
* [KronScheduler.next] will always return [com.soywiz.klock.DateTime.now] * [KronScheduler.next] will always return [com.soywiz.klock.DateTime.now]
*/ */
val AnyTimeScheduler: KronScheduler by lazy { val AnyTimeScheduler: KronScheduler by lazy {
CronDateTimeScheduler(listOf(anyCronDateTime)) CronDateTimeScheduler(anyCronDateTime)
} }
/** /**
@ -56,4 +56,4 @@ val EveryMonthScheduler: KronScheduler by lazy {
*/ */
val EveryYearScheduler: KronScheduler by lazy { val EveryYearScheduler: KronScheduler by lazy {
buildSchedule { years { 0 every 1 } } buildSchedule { years { 0 every 1 } }
} }

View File

@ -116,7 +116,7 @@ fun createSimpleScheduler(
scheduler scheduler
} else { } else {
CronDateTimeSchedulerTz( CronDateTimeSchedulerTz(
(scheduler as CronDateTimeScheduler).cronDateTimes, (scheduler as CronDateTimeScheduler).cronDateTime,
TimezoneOffset(defaultOffset.minutes) TimezoneOffset(defaultOffset.minutes)
) )
} }

View File

@ -38,16 +38,16 @@ data class CollectionKronScheduler internal constructor(
) )
} }
is CronDateTimeSchedulerTz -> { is CronDateTimeSchedulerTz -> {
val newCronDateTimes = kronScheduler.cronDateTimes.toMutableList() val newCronDateTimes = mutableListOf(kronScheduler.cronDateTime)
val cronDateTimes = schedulers.removeAll { schedulers.removeAll {
if (it is CronDateTimeSchedulerTz && it.offset == kronScheduler.offset) { if (it is CronDateTimeSchedulerTz && it.offset == kronScheduler.offset) {
newCronDateTimes.addAll(it.cronDateTimes) newCronDateTimes.add(it.cronDateTime)
true true
} else { } else {
false false
} }
} }
schedulers.add(CronDateTimeSchedulerTz(newCronDateTimes.toList(), kronScheduler.offset)) schedulers.add(CronDateTimeSchedulerTz(newCronDateTimes.merge(), kronScheduler.offset))
} }
is CollectionKronScheduler -> kronScheduler.schedulers.forEach { is CollectionKronScheduler -> kronScheduler.schedulers.forEach {
include(it) include(it)

View File

@ -2,105 +2,63 @@ package dev.inmo.krontab.internal
import com.soywiz.klock.* import com.soywiz.klock.*
import dev.inmo.krontab.KronScheduler import dev.inmo.krontab.KronScheduler
import dev.inmo.krontab.utils.copy
/** /**
* @param dayOfweek 0-6 * @param daysOfWeek 0-6
* @param year any int * @param years any int
* @param month 0-11 * @param months 0-11
* @param dayOfMonth 0-31 * @param daysOfMonth 0-31
* @param hours 0-23 * @param hours 0-23
* @param minutes 0-59 * @param minutes 0-59
* @param seconds 0-59 * @param seconds 0-59
*/ */
internal data class CronDateTime( internal data class CronDateTime(
val dayOfweek: Byte? = null, val daysOfWeek: Array<Byte>? = null,
val year: Int? = null, val years: Array<Int>? = null,
val month: Byte? = null, val months: Array<Byte>? = null,
val dayOfMonth: Byte? = null, val daysOfMonth: Array<Byte>? = null,
val hours: Byte? = null, val hours: Array<Byte>? = null,
val minutes: Byte? = null, val minutes: Array<Byte>? = null,
val seconds: Byte? = null val seconds: Array<Byte>? = null
) { ) {
init { init {
check(dayOfweek ?.let { it in dayOfWeekRange } ?: true) check(daysOfWeek ?.all { it in dayOfWeekRange } ?: true)
check(year ?.let { it in yearRange } ?: true) check(years?.all { it in yearRange } ?: true)
check(month ?.let { it in monthRange } ?: true) check(months?.all { it in monthRange } ?: true)
check(dayOfMonth ?.let { it in dayOfMonthRange } ?: true) check(daysOfMonth ?.all { it in dayOfMonthRange } ?: true)
check(hours?.let { it in hoursRange } ?: true) check(hours?.all { it in hoursRange } ?: true)
check(minutes?.let { it in minutesRange } ?: true) check(minutes?.all { it in minutesRange } ?: true)
check(seconds?.let { it in secondsRange } ?: true) check(seconds?.all { it in secondsRange } ?: true)
} }
internal val klockDayOfMonth = dayOfMonth ?.plus(1) internal val calculators = listOf(
internal val dayOfWeekInt: Int? = dayOfweek ?.toInt() 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) },
)
/** internal fun toNearDateTime(relativelyTo: DateTime = DateTime.now()): DateTime? {
* THIS METHOD WILL <b>NOT</b> TAKE CARE ABOUT [offset] PARAMETER. It was decided due to the fact that we unable to get var current = relativelyTo
* real timezone offset from simple [DateTime] whileLoop@while (true) {
* for (calculator in calculators) {
* @return The near [DateTime] which happens after [relativelyTo] or will be equal to [relativelyTo] val (calculated, requireRecalculation) = (calculator ?: continue).calculateNearTime(current) ?: return null
*/ current = calculated
internal fun CronDateTime.toNearDateTime(relativelyTo: DateTime = DateTime.now()): DateTime? { if (requireRecalculation) {
var current = relativelyTo continue@whileLoop
}
val weekDay = dayOfWeekInt
if (weekDay != null && current.dayOfWeek.index0 != weekDay) {
do {
var diff = weekDay - current.dayOfWeek.index0
if (diff < 0) {
diff += 7 /* days in week */
} }
current = (current + diff.days).startOfDay return current
val next = toNearDateTime(current)
if (next == null || next.dayOfWeek.index0 == weekDay) {
return next
}
} while (true)
}
seconds?.let {
val left = it - current.seconds
current += DateTimeSpan(minutes = if (left <= 0) 1 else 0, seconds = left)
}
minutes?.let {
val left = it - current.minutes
current += DateTimeSpan(hours = if (left < 0) 1 else 0, minutes = left)
}
hours?.let {
val left = it - current.hours
current += DateTimeSpan(days = if (left < 0) 1 else 0, hours = left)
}
klockDayOfMonth ?.let {
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)
}
month ?.let {
val left = it - current.month0
current += DateTimeSpan(years = if (left < 0) 1 else 0, months = left)
}
year ?.let {
if (current.yearInt != it) {
return null
} }
} }
return current
} }
internal fun createCronDateTimeList( internal fun createCronDateTime(
seconds: Array<Byte>? = null, seconds: Array<Byte>? = null,
minutes: Array<Byte>? = null, minutes: Array<Byte>? = null,
hours: Array<Byte>? = null, hours: Array<Byte>? = null,
@ -108,38 +66,8 @@ internal fun createCronDateTimeList(
month: Array<Byte>? = null, month: Array<Byte>? = null,
years: Array<Int>? = null, years: Array<Int>? = null,
weekDays: Array<Byte>? = null weekDays: Array<Byte>? = null
): List<CronDateTime> { ): CronDateTime {
val resultCronDateTimes = mutableListOf(CronDateTime()) return CronDateTime(weekDays, years, month, dayOfMonth, hours, minutes, seconds)
seconds ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Byte ->
previousCronDateTime.copy(seconds = currentTime)
}
minutes ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Byte ->
previousCronDateTime.copy(minutes = currentTime)
}
hours ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Byte ->
previousCronDateTime.copy(hours = currentTime)
}
dayOfMonth ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Byte ->
previousCronDateTime.copy(dayOfMonth = currentTime)
}
month ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Byte ->
previousCronDateTime.copy(month = currentTime)
}
years ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Int ->
previousCronDateTime.copy(year = currentTime)
}
weekDays ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Byte ->
previousCronDateTime.copy(dayOfweek = currentTime)
}
return resultCronDateTimes.toList()
} }
/** /**
@ -153,7 +81,7 @@ internal fun createKronScheduler(
month: Array<Byte>? = null, month: Array<Byte>? = null,
years: Array<Int>? = null, years: Array<Int>? = null,
weekDays: Array<Byte>? = null weekDays: Array<Byte>? = null
): KronScheduler = CronDateTimeScheduler(createCronDateTimeList(seconds, minutes, hours, dayOfMonth, month, years, weekDays)) ): KronScheduler = CronDateTimeScheduler(createCronDateTime(seconds, minutes, hours, dayOfMonth, month, years, weekDays))
/** /**
* @return [KronScheduler] (in fact [CronDateTimeScheduler]) based on incoming data * @return [KronScheduler] (in fact [CronDateTimeScheduler]) based on incoming data
*/ */
@ -166,4 +94,14 @@ internal fun createKronSchedulerWithOffset(
years: Array<Int>? = null, years: Array<Int>? = null,
weekDays: Array<Byte>? = null, weekDays: Array<Byte>? = null,
offset: TimezoneOffset offset: TimezoneOffset
): KronScheduler = CronDateTimeSchedulerTz(createCronDateTimeList(seconds, minutes, hours, dayOfMonth, month, years, weekDays), offset) ): KronScheduler = CronDateTimeSchedulerTz(createCronDateTime(seconds, minutes, hours, dayOfMonth, month, years, weekDays), offset)
internal fun List<CronDateTime>.merge() = CronDateTime(
flatMap { it.daysOfWeek ?.toList() ?: emptyList() }.distinct().toTypedArray().takeIf { it.isNotEmpty() },
flatMap { it.years ?.toList() ?: emptyList() }.distinct().toTypedArray().takeIf { it.isNotEmpty() },
flatMap { it.months ?.toList() ?: emptyList() }.distinct().toTypedArray().takeIf { it.isNotEmpty() },
flatMap { it.daysOfMonth ?.toList() ?: emptyList() }.distinct().toTypedArray().takeIf { it.isNotEmpty() },
flatMap { it.hours ?.toList() ?: emptyList() }.distinct().toTypedArray().takeIf { it.isNotEmpty() },
flatMap { it.minutes ?.toList() ?: emptyList() }.distinct().toTypedArray().takeIf { it.isNotEmpty() },
flatMap { it.seconds ?.toList() ?: emptyList() }.distinct().toTypedArray().takeIf { it.isNotEmpty() },
)

View File

@ -19,7 +19,7 @@ import dev.inmo.krontab.collection.plus
* @see dev.inmo.krontab.builder.SchedulerBuilder * @see dev.inmo.krontab.builder.SchedulerBuilder
*/ */
internal data class CronDateTimeScheduler internal constructor( internal data class CronDateTimeScheduler internal constructor(
internal val cronDateTimes: List<CronDateTime> internal val cronDateTime: CronDateTime
) : KronScheduler { ) : KronScheduler {
/** /**
* @return Near date using [cronDateTimes] list and getting the [Iterable.minByOrNull] one * @return Near date using [cronDateTimes] list and getting the [Iterable.minByOrNull] one
@ -27,12 +27,14 @@ internal data class CronDateTimeScheduler internal constructor(
* @see toNearDateTime * @see toNearDateTime
*/ */
override suspend fun next(relatively: DateTime): DateTime? { override suspend fun next(relatively: DateTime): DateTime? {
return cronDateTimes.mapNotNull { it.toNearDateTime(relatively) }.minOrNull() return cronDateTime.toNearDateTime(relatively)
} }
} }
internal fun mergeCronDateTimeSchedulers(schedulers: List<CronDateTimeScheduler>) = CronDateTimeScheduler( internal fun mergeCronDateTimeSchedulers(
schedulers.flatMap { it.cronDateTimes } schedulers: List<CronDateTimeScheduler>
): CronDateTimeScheduler = CronDateTimeScheduler(
schedulers.map { it.cronDateTime }.merge()
) )
/** /**

View File

@ -11,14 +11,12 @@ import dev.inmo.krontab.KronSchedulerTz
* @see CronDateTime * @see CronDateTime
*/ */
internal data class CronDateTimeSchedulerTz internal constructor( internal data class CronDateTimeSchedulerTz internal constructor(
internal val cronDateTimes: List<CronDateTime>, internal val cronDateTime: CronDateTime,
internal val offset: TimezoneOffset internal val offset: TimezoneOffset
) : KronSchedulerTz { ) : KronSchedulerTz {
override suspend fun next(relatively: DateTimeTz): DateTimeTz? { override suspend fun next(relatively: DateTimeTz): DateTimeTz? {
val dateTimeWithActualOffset = relatively.toOffset(offset).local val dateTimeWithActualOffset = relatively.toOffset(offset).local
return cronDateTimes.mapNotNull { return cronDateTime.toNearDateTime(dateTimeWithActualOffset) ?.toOffsetUnadjusted(offset) ?.toOffset(relatively.offset)
it.toNearDateTime(dateTimeWithActualOffset)
}.minOrNull() ?.toOffsetUnadjusted(offset) ?.toOffset(relatively.offset)
} }
} }
@ -27,5 +25,8 @@ internal fun mergeCronDateTimeSchedulers(
) = schedulers.groupBy { ) = schedulers.groupBy {
it.offset it.offset
}.map { (offset, schedulers) -> }.map { (offset, schedulers) ->
CronDateTimeSchedulerTz(schedulers.flatMap { it.cronDateTimes }, offset) CronDateTimeSchedulerTz(
schedulers.map { it.cronDateTime }.merge(),
offset
)
} }

View File

@ -0,0 +1,183 @@
package dev.inmo.krontab.internal
import com.soywiz.klock.*
import dev.inmo.krontab.utils.copy
import kotlin.math.min
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<DateTime, Boolean>?
}
internal class CommonNearDateTimeCalculator<T>(
private val times: Array<T>,
private val partGetter: (DateTime) -> T,
private val partSetter: (DateTime, T) -> DateTime?
) : NearDateTimeCalculator where T : Comparable<T>, 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<DateTime, Boolean>? {
val currentData = partGetter(relativelyTo)
val greaterOrEquals = times.firstOrNull { it >= currentData }
val newDateTime = when (greaterOrEquals) {
null -> partSetter(relativelyTo, times.first()) ?: return null
currentData -> relativelyTo
else -> partSetter(relativelyTo, greaterOrEquals) ?: return null
}
return if (newDateTime == relativelyTo) {
relativelyTo to false
} else {
newDateTime to true
}
}
}
internal fun NearDateTimeCalculatorMillis(
times: Array<Short>
) = CommonNearDateTimeCalculator(
times,
{ it.milliseconds.toShort() },
{ dateTime, newOne ->
(if (newOne < dateTime.milliseconds) {
dateTime.plus(1.seconds)
} else {
dateTime
}).copy(milliseconds = newOne.toInt())
}
)
internal fun NearDateTimeCalculatorSeconds(
times: Array<Byte>
) = CommonNearDateTimeCalculator(
times,
{ it.seconds.toByte() },
{ dateTime, newOne ->
(if (newOne < dateTime.seconds) {
dateTime.plus(1.minutes)
} else {
dateTime
}).copy(second = newOne.toInt(), milliseconds = 0)
}
)
internal fun NearDateTimeCalculatorMinutes(
times: Array<Byte>
) = CommonNearDateTimeCalculator(
times,
{ it.minutes.toByte() },
{ dateTime, newOne ->
(if (newOne < dateTime.minutes) {
dateTime.plus(1.hours)
} else {
dateTime
}).copy(minute = newOne.toInt(), second = 0, milliseconds = 0)
}
)
internal fun NearDateTimeCalculatorHours(
times: Array<Byte>
) = CommonNearDateTimeCalculator(
times,
{ it.hours.toByte() },
{ dateTime, newOne ->
(if (newOne < dateTime.hours) {
dateTime.plus(1.days)
} else {
dateTime
}).copy(hour = newOne.toInt(), minute = 0, second = 0, milliseconds = 0)
}
)
internal fun NearDateTimeCalculatorDays(
times: Array<Byte>
) = CommonNearDateTimeCalculator(
times,
{ it.dayOfMonth.toByte() },
{ dateTime, newOne ->
(if (newOne < dateTime.dayOfMonth) {
dateTime.plus(1.months)
} else {
dateTime
}).copy(
dayOfMonth = min(dateTime.month.days(dateTime.year), newOne.toInt() + 1), // index1
hour = 0,
minute = 0,
second = 0,
milliseconds = 0
)
}
)
internal fun NearDateTimeCalculatorMonths(
times: Array<Byte>
) = CommonNearDateTimeCalculator(
times,
{ it.dayOfMonth.toByte() },
{ dateTime, newOne ->
(if (newOne < dateTime.month0) {
dateTime.plus(1.years)
} else {
dateTime
}).copy(
month = newOne.toInt() + 1, // index1
dayOfMonth = 1, // index1
hour = 0,
minute = 0,
second = 0,
milliseconds = 0
)
}
)
internal fun NearDateTimeCalculatorWeekDays(
times: Array<Byte>
) = 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 {
dateTime.plus(newOne.toInt().days - currentDayOfWeek.days)
}).copy(
hour = 0,
minute = 0,
second = 0,
milliseconds = 0
)
}
)
internal fun NearDateTimeCalculatorYears(
times: Array<Int>
) = CommonNearDateTimeCalculator(
times,
{ it.yearInt },
{ dateTime, newOne ->
val currentYear = dateTime.yearInt
if (newOne == currentYear) return@CommonNearDateTimeCalculator dateTime
(if (newOne < currentYear) {
null
} else {
dateTime.plus(newOne.years - currentYear.years)
}) ?.copy(
month = 1, // index1
dayOfMonth = 1, // index1
hour = 0,
minute = 0,
second = 0,
milliseconds = 0
)
}
)

View File

@ -8,7 +8,7 @@ private fun <T> createSimpleScheduler(from: String, dataRange: IntRange, dataCon
val things = from.split(",") val things = from.split(",")
val results = things.flatMap { val results = things.flatMap {
val currentToken = it.toLowerCase().replace( val currentToken = it.lowercase().replace(
"f", dataRange.first.toString() "f", dataRange.first.toString()
).replace( ).replace(
"l", dataRange.last.toString() "l", dataRange.last.toString()

View File

@ -0,0 +1,22 @@
package dev.inmo.krontab.utils
import com.soywiz.klock.*
import kotlin.math.min
fun DateTime.copy(
year: Int = yearInt,
month: Int = month1,
dayOfMonth: Int = this.dayOfMonth,
hour: Int = hours,
minute: Int = minutes,
second: Int = seconds,
milliseconds: Int = this.milliseconds
) = DateTime(
year,
month,
min(Month(month).days(yearInt), dayOfMonth),
hour,
minute,
second,
milliseconds
)

View File

@ -15,9 +15,16 @@ import kotlinx.coroutines.flow.*
*/ */
@FlowPreview @FlowPreview
fun KronScheduler.asTzFlow(): Flow<DateTimeTz> = channelFlow { fun KronScheduler.asTzFlow(): Flow<DateTimeTz> = channelFlow {
var previousTime = DateTime.nowLocal()
while (isActive) { while (isActive) {
val now = DateTime.now().local val now = DateTime.nowLocal()
val nextTime = next(now) ?: break val nextTime = next(now) ?: break
if (previousTime == nextTime) {
delay(1L) // skip 1ms
continue
} else {
previousTime = nextTime
}
val sleepDelay = (nextTime - DateTime.now().local).millisecondsLong val sleepDelay = (nextTime - DateTime.now().local).millisecondsLong
delay(sleepDelay) delay(sleepDelay)
send(nextTime) send(nextTime)
@ -48,4 +55,4 @@ class SchedulerFlow(
collector.emit(nextTime) collector.emit(nextTime)
} }
} }
} }

View File

@ -67,8 +67,8 @@ class StringParseTest {
val flow = kronScheduler.asFlow() val flow = kronScheduler.asFlow()
runTest { runTest {
val ranges = rangesEnds.map { it.first .. it.second }.flatten().toMutableList() val ranges = rangesEnds.map { it.first .. it.second }.flatten().distinct().toMutableList()
val expectedCollects = rangesEnds.sumOf { it.second - it.first + 1 } val expectedCollects = ranges.size
var collected = 0 var collected = 0
flow.takeWhile { ranges.isNotEmpty() }.collect { flow.takeWhile { ranges.isNotEmpty() }.collect {
@ -80,7 +80,7 @@ class StringParseTest {
} }
@Test @Test
fun testThatTimezoneCorrectlyDeserialized() { fun testThatTimezoneCorrectlyDeserialized() {
val now = DateTimeTz.nowLocal() val now = DateTime.now().copy(milliseconds = 0).local
runTest { runTest {
for (i in 0 .. 1339) { for (i in 0 .. 1339) {

View File

@ -10,7 +10,8 @@ class TimeZoneTest {
@Test @Test
fun testDifferentTimeZonesReturnsDifferentTimes() { fun testDifferentTimeZonesReturnsDifferentTimes() {
val scheduler = buildSchedule { seconds { every(1) } } val scheduler = buildSchedule { seconds { every(1) } }
val baseDate = DateTime.now().startOfWeek val additionalMilliseconds = 100.milliseconds
val baseDate = DateTime.now().startOfWeek.copy(milliseconds = additionalMilliseconds.millisecondsInt)
runTest { runTest {
for (i in 0 until 7) { for (i in 0 until 7) {
val now = baseDate + i.days val now = baseDate + i.days
@ -18,10 +19,10 @@ class TimeZoneTest {
val nowTz = now.toOffset(j.hours) val nowTz = now.toOffset(j.hours)
val next = scheduler.next(nowTz)!! val next = scheduler.next(nowTz)!!
assertEquals( assertEquals(
(nowTz + 1.seconds).utc.unixMillisLong, next.utc.unixMillisLong (nowTz + 1.seconds - additionalMilliseconds).utc.unixMillisLong, next.utc.unixMillisLong
) )
} }
} }
} }
} }
} }