moon-schedule

    Deterministic UTC Cron and RFC 5545 recurrence rules for MoonBit.

    cron
    rrule
    schedule
    calendar
    utc
    Download zip
    Author
    Version
    0.1.0
    License
    MIT
    Last updated
    3 months ago
    Downloads
    44

    No dependencies

    #MoonSchedule

    MoonSchedule 是一个纯 MoonBit 的确定性 UTC 日程规则引擎。它覆盖五字段 Cron 与 RFC 5545 RRULE 的实用子集,可用于跨 wasm、wasm-gc、js、native 后端计算下一次触发时间或一个时间区间内的复发实例。

    #为什么需要它

    MoonBit 已有日期时间实现,但面向工程定时(Cron)与可互操作日历复发规则(RRULE)的纯 MoonBit 规则引擎仍是生态空缺。MoonSchedule 不读取系统时间、不做时区或 DST 猜测;同一输入在每个后端都会得到相同 UTC 结果。

    #安装

    发布后:

    moon add 100kkk/moon-schedule

    本地开发:

    moon check --target all --deny-warn moon test --target all --deny-warn

    #功能范围

    • DateTime:带分钟精度的 UTC RFC 3339 时间、闰年/月末/星期计算。
    • Cron:*、列表、范围、步长、月份和星期英文别名;遵循传统 Cron 的 DOM/DOW OR 语义。
    • RRule:FREQ(DAILY/WEEKLY/MONTHLY/YEARLY)、INTERVAL、COUNT、UNTIL、BYDAY、BYMONTHDAY、BYMONTH。
    • CLI:解析、下一次触发模拟、区间枚举。

    首版明确不支持时区、DST、秒字段、BYSETPOS、EXDATE 和完整 iCalendar 文档;它们是后续 4k 行规模路线图中的独立功能。

    #API 示例

    let cron = @schedule.Cron::parse("*/15 9-17 * * MON-FRI")
    let after = @schedule.DateTime::parse("2025-01-06T09:01Z")
    let next = cron.next_after(after)
    // 2025-01-06T09:15Z

    let rule = @schedule.RRule::parse("FREQ=DAILY;COUNT=3")
    let start = @schedule.DateTime::parse("2025-01-01T09:00Z")
    let end = @schedule.DateTime::parse("2025-01-05T09:00Z")
    let occurrences = rule.occurrences_between(start, end)

    #CLI

    PowerShell 中请将包含空格或分号的规则整体加引号:

    moon run cmd/main -- parse 'cron:*/15 9-17 * * MON-FRI' moon run cmd/main -- next 'cron:0 0 1 JAN *' '2024-12-31T23:59Z' 2 moon run cmd/main -- between 'rrule:FREQ=DAILY;COUNT=3' '2025-01-01T09:00Z' '2025-01-05T09:00Z'

    #质量与发布

    CI 对四个稳定后端执行检查、构建、格式检查、接口生成、测试和 moon package。项目采用 MIT 许可证。发布前运行:

    moon check --target all --deny-warn moon build --target all --deny-warn moon fmt --check moon info git diff --exit-code moon test --target all --deny-warn moon package

    #路线图

    1. 规则集合、EXDATE/RDATE 与人类可读描述。
    2. RFC 5545 更多 BY* 字段与性质测试。
    3. 时区适配层、DST 策略与性能基准。

    #许可证

    MIT。

    ScheduleError

    pub suberror ScheduleError {
    InvalidDate(String)
    InvalidRule(String)
    }

    Cron

    pub struct Cron {
    minutes : Array[Bool]
    hours : Array[Bool]
    days : Array[Bool]
    months : Array[Bool]
    weekdays : Array[Bool]
    days_wildcard : Bool
    weekdays_wildcard : Bool
    } derive(
    Debug
    )

    Cron::matches

    fn Cron::matches(self : Cron, at : DateTime) -> Bool

    Cron::next_after

    fn Cron::next_after(self : Cron, after : DateTime) -> DateTime raise ScheduleError

    Return the first matching minute strictly after after, searching at most two years.

    Cron::parse

    fn Cron::parse(input : String) -> Cron raise ScheduleError

    Parse a five-field UTC cron expression: minute hour day-of-month month day-of-week.

    DateTime

    pub struct DateTime {
    year : Int
    month : Int
    day : Int
    hour : Int
    minute : Int
    } derive(Compare, Eq,
    Debug
    )

    DateTime::add_minutes

    fn DateTime::add_minutes(self : DateTime, amount : Int) -> DateTime

    DateTime::new

    fn DateTime::new(year : Int, month : Int, day : Int, hour : Int, minute : Int) -> DateTime raise ScheduleError

    DateTime::next_day

    fn DateTime::next_day(self : DateTime) -> DateTime

    DateTime::parse

    fn DateTime::parse(input : String) -> DateTime raise ScheduleError

    DateTime::to_string

    fn DateTime::to_string(self : DateTime) -> String

    DateTime::weekday

    fn DateTime::weekday(self : DateTime) -> Int

    Frequency

    pub enum Frequency {
    Daily
    Weekly
    Monthly
    Yearly
    } derive(Eq,
    Debug
    )

    RRule

    pub struct RRule {
    frequency : Frequency
    interval : Int
    count : Int?
    until : DateTime?
    weekdays : Array[Int]
    monthdays : Array[Int]
    months : Array[Int]
    } derive(
    Debug
    )

    RRule::next_after

    fn RRule::next_after(self : RRule, after : DateTime) -> DateTime?

    RRule::occurrences_between

    fn RRule::occurrences_between(self : RRule, start : DateTime, end : DateTime) -> Array[DateTime]

    Enumerate occurrences in [start, end]; start is the recurrence anchor.

    RRule::parse

    fn RRule::parse(input : String) -> RRule raise ScheduleError

    Parse the UTC-safe RFC 5545 subset used by MoonSchedule.

    days_in_month

    fn days_in_month(year : Int, month : Int) -> Int

    is_leap_year

    fn is_leap_year(year : Int) -> Bool