All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.internal.CronDateTime.kt Maven / Gradle / Ivy

The newest version!
package dev.inmo.krontab.internal

import korlibs.time.DateTime
import korlibs.time.TimezoneOffset
import dev.inmo.krontab.KronScheduler

/**
 * @param daysOfWeek 0-6
 * @param years any int
 * @param months 0-11
 * @param daysOfMonth 0-30
 * @param hours 0-23
 * @param minutes 0-59
 * @param seconds 0-59
 */
internal data class CronDateTime(
    val daysOfWeek: Array? = null,
    val years: Array? = null,
    val months: Array? = null,
    val daysOfMonth: Array? = null,
    val hours: Array? = null,
    val minutes: Array? = null,
    val seconds: Array? = null,
    val milliseconds: Array? = millisecondsArrayDefault
) {
    init {
        check(daysOfWeek ?.all { it in dayOfWeekRange } ?: true)
        check(years?.all { it in yearRange } ?: true)
        check(months?.all { it in monthRange } ?: true)
        check(daysOfMonth ?.all { it in dayOfMonthRange } ?: true)
        check(hours?.all { it in hoursRange } ?: true)
        check(minutes?.all { it in minutesRange } ?: true)
        check(seconds?.all { it in secondsRange } ?: true)
        check(milliseconds?.all { it in millisecondsRange } ?: true)
    }

    internal val calculators = listOf(
        years ?.let { NearDateTimeCalculatorYears(it) },
        daysOfWeek ?.let { NearDateTimeCalculatorWeekDays(it) },
        milliseconds ?.let { NearDateTimeCalculatorMillis(it) },
        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? {
        var current = relativelyTo
        whileLoop@while (true) {
            for (calculator in calculators) {
                val (calculated, requireRecalculation) = (calculator ?: continue).calculateNearTime(current) ?: return null
                current = calculated
                if (requireRecalculation) {
                    continue@whileLoop
                }
            }
            return current
        }
    }
}

internal fun createCronDateTime(
    seconds: Array? = null,
    minutes: Array? = null,
    hours: Array? = null,
    dayOfMonth: Array? = null,
    month: Array? = null,
    years: Array? = null,
    weekDays: Array? = null,
    milliseconds: Array? = millisecondsArrayDefault
): CronDateTime {
    return CronDateTime(weekDays, years, month, dayOfMonth, hours, minutes, seconds, milliseconds)
}

/**
 * @return [KronScheduler] (in fact [CronDateTimeScheduler]) based on incoming data
 */
internal fun createKronScheduler(
    seconds: Array? = null,
    minutes: Array? = null,
    hours: Array? = null,
    dayOfMonth: Array? = null,
    month: Array? = null,
    years: Array? = null,
    weekDays: Array? = null,
    milliseconds: Array? = millisecondsArrayDefault
): KronScheduler = CronDateTimeScheduler(
    createCronDateTime(
        seconds,
        minutes,
        hours,
        dayOfMonth,
        month,
        years,
        weekDays,
        milliseconds
    )
)
/**
 * @return [KronScheduler] (in fact [CronDateTimeScheduler]) based on incoming data
 */
internal fun createKronSchedulerWithOffset(
    seconds: Array? = null,
    minutes: Array? = null,
    hours: Array? = null,
    dayOfMonth: Array? = null,
    month: Array? = null,
    years: Array? = null,
    weekDays: Array? = null,
    offset: TimezoneOffset,
    milliseconds: Array? = millisecondsArrayDefault
): KronScheduler = CronDateTimeSchedulerTz(
    createCronDateTime(
        seconds,
        minutes,
        hours,
        dayOfMonth,
        month,
        years,
        weekDays,
        milliseconds
    ),
    offset
)

internal fun List.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() },
    flatMap { it.milliseconds ?.toList() ?: listOf(0) }.distinct().toTypedArray().takeIf { it.isNotEmpty() },
)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy