10个不稳定版本 (3个破坏性更新)

0.4.2 2022年3月12日
0.4.1 2022年3月8日
0.4.0 2021年12月4日
0.3.1 2021年6月10日
0.1.1 2021年2月6日

#cron-expression中的第24

MIT许可证

57KB
1K SLoC

cron-lingo

一个小的Rust库,用于解析类似cron的、可读的表达式,如"在周一早上6点,在周六和周日下午6点",并使用它迭代即将到来的日期。

主要目标是提供一种更可预测的方式来调度关键任务,例如通过去除标准cron的一些核心功能。此外,表达式语法在很大程度上是自解释的,这可能对计划将某些调度器的配置暴露给非技术人员具有有用的副作用。

示例

use cron_lingo::Schedule;
use std::str::FromStr;

fn main() {
    let schedule = Schedule::from_str("at 1 PM on Mondays").unwrap();

    for date in schedule.iter().unwrap().take(3) {
        println!("{}", date);
    }
}

// Output:
// 2021-06-14 13:00 +2
// 2021-06-21 13:00 +2
// 2021-06-28 13:00 +2

请参阅docs.rs上的模块级文档,了解应用语法的具体细节。


lib.rs:

此包允许解析类似cron的、可读的表达式。结果对象可以被转换成迭代器,按顺序计算下一个日期(作为一个time::OffsetDateTime)。默认情况下,日期是在当前本地偏移量下计算的,但迭代器可以被配置为使用其他偏移量。

示例

use cron_lingo::Schedule;
use std::str::FromStr;
use time::macros::offset;

fn main() -> Result<(), cron_lingo::error::Error> {
    // Create a schedule from an expression and iterate.
    let expr = "at 6:30 AM on Mondays and Thursdays";
    let schedule1 = Schedule::from_str(expr)?;
    assert!(schedule1.iter()?.next().is_some());

    // Create another schedule, add it to the first, and then iterate.
    let schedule2 = Schedule::from_str("at 8 PM on the first Sunday")?;
    let mut combination = schedule1 + schedule2;
    assert!(combination.iter()?.next().is_some());

    // Finally add another to the existing collection of schedules.
    let schedule3 = Schedule::from_str("at 12:00 PM on the last Friday")?;
    combination += schedule3;
    assert!(combination.iter()?.next().is_some());

    // The examples above assume that the current local offset is to
    // be used to determine the dates, but dates can also be computed
    // in different offsets.
    let expr = "at 6:30 AM on Mondays and Thursdays";
    let schedule = Schedule::from_str(expr)?;
    assert!(schedule.iter()?.assume_offset(offset!(+3)).next().is_some());
    Ok(())
}

表达式语法

一个表达式由三个部分组成:一个时间指定,以及可选的星期和星期指定。

<时间指定> [<星期指定>] [<星期指定>]

以下是一些完整的表达式的随机示例

  • 在1点
  • 在周六和周日下午6点
  • 在2点(周一,周四)的偶数周
  • 在周三下午6:45
  • 在周一早上6点
  • 在早上6点,下午6点(周一)
  • 在第一个周日早上8点

以下表格为每种指定类型提供了一些示例

时间 星期(可选) 星期(可选)
每个整点 在周一和周二 在奇数周
早上7:30和下午7:30 在周二和周六 在偶数周
早上6点,下午6点,晚上8点 在周五
早上6点,午夜,下午6点
早上8:30 在奇数周
早上8点 在周三
08点 在第一个周一
晚上8点 在第四个周五 在偶数周
晚上8点 在周三和周日
早上5:45 (周一和周四)
早上6点和下午6点 (第一个周日)
下午1:15 (第一个周一和第二个周五)
下午1点 在第三个周一
下午1:50 在第3个星期一
下午1点 在第4个星期六
下午6点 在最后一个星期一

规则集

上述示例覆盖了表达式语法的基礎規則,在一定程度(對於大多數用例可能足夠)上。然而,以下是一個列表,列出了表达式必須遵守的“規則”,這可能會對您避免錯誤有幫助:

時間指定

  • 必須以開頭
  • 然後是每個整點或一個獨特的時間列表
  • 一個時間遵循12小時鐘,所以是一個從1到12的數字後面跟著AMPM(大寫!),例如1 AM或1 PM
  • 一個時間也可以包含從00到59的分鐘(用冒號與小時分隔)。省略分鐘表示整點,例如8 PM == 8:00 PM
  • 獨特的時間由逗號連接

星期指定

  • 可選的
  • 跟在時間規指定之後
  • 由一個星期列表組成,其中包含選擇特定月份星期幾的修飾符
  • 列表開始於或用簡單花括號()括起來以增加簡潔性
  • 星期必須是以下之一[星期一 | 星期二 | 星期三 | 星期四 | 星期五 | 星期六 | 星期日],如果例如每個星期一都要包括,則後面附上s,或是一個前面有修飾符的星期[第一 | 1st | 第二 | 2nd | 第三 | 3rd | 第四 | 4th | 最後]以僅包含特定月份的星期幾。

星期指定

  • 可選的
  • 必須是偶數星期 / 奇數星期

依賴性

~755KB
~14K SLoC