#cron-expression #cron #day-week #job-scheduler #task #task-scheduler #job

croner

功能全面、轻量级且高效的 Rust 库,用于解析和评估 cron 模式

20 个版本 (10 个稳定版本)

2.0.5 2024 年 7 月 24 日
2.0.4 2024 年 1 月 3 日
2.0.3 2023 年 12 月 20 日
1.0.5 2023 年 12 月 11 日
0.0.10 2023 年 11 月 27 日

#18日期和时间

Download history 92/week @ 2024-04-29 407/week @ 2024-05-06 873/week @ 2024-05-13 5204/week @ 2024-05-20 3446/week @ 2024-05-27 2388/week @ 2024-06-03 842/week @ 2024-06-10 999/week @ 2024-06-17 1309/week @ 2024-06-24 826/week @ 2024-07-01 1489/week @ 2024-07-08 1517/week @ 2024-07-15 1542/week @ 2024-07-22 1034/week @ 2024-07-29 1660/week @ 2024-08-05 705/week @ 2024-08-12

4,967 每月下载量
用于 5 个 crate (4 个直接使用)

MIT 许可证

120KB
2K SLoC

克诺勒

克诺勒是一个功能全面、轻量级且高效的 Rust 库,用于解析和评估 cron 模式。

这是流行的 JavaScript/TypeScript cron 解析器 croner 的 Rust 版本。

功能

  • 解析和评估 cron 表达式以计算即将执行的运行时间。
  • 遵循 POSIX/Vixie-cron 标准,同时通过添加额外的指定符扩展它,例如 L 用于月份的最后一天和星期几,# 用于月份的第 n 个星期几,W 用于与月份某一天最接近的星期几。
  • 评估不同时区的 cron 表达式。
  • 支持可选的秒精度 .with_seconds_optional.with_seconds_required
  • 支持可选的替代星期几模式,使用 with_alternative_weekdays 以石英风格的星期几代替 POSIX。
  • 允许灵活组合 DOM 和 DOW 条件,使模式能够匹配月份特定周的特定星期或特定日期的最接近的星期几。
  • chrono 和(可选)chrono-tz 兼容。
  • 强大的错误处理。

为什么选择 croner 而不是 cron 或 saffron?

克诺勒结合了 cron 和 saffron 的功能,同时遵循 POSIX/Vixie 的“标准”的相关部分。请参阅此表格

功能 克诺勒 cron saffron
时区 X X
范围 (15-25) X X X
带有步进的范围 (15-25/2) X X X
L - 月份的最后一天 X X
5#L - 星期几的最后出现 X X
5L - 星期几的最后出现 X ? X
# - 第N个星期几 X X
W - 最接近的星期几 X X
符合“标准”的星期几(1代表星期一) X
五部分模式(分钟粒度) X X
六部分模式(秒粒度) X X
星期几/月份的文本表示 X X X
别名(例如 @hourly 等) X X
与chrono DateTime 兼容 X X X
DOM-and-DOW选项 X

注意 在2023-12-02使用 cron@0.12.0saffron@.0.1.0

入门指南

先决条件

确保您的机器上已安装Rust。如果没有,您可以从官方Rust网站获取。

安装

croner 添加到您的 Cargo.toml 依赖项中

[dependencies]
croner = "2.0.5" # Adjust the version as necessary

用法

以下是一个快速示例,帮助您开始匹配当前时间,并找到下一个发生的时间。 is_time_matching 接收一个 chrono DateTime

use croner::Cron;
use chrono::Local;

fn main() {

    // Parse cron expression
    let cron_all = Cron::new("18 * * * 5")
      .parse()
      .expect("Couldn't parse cron string");

    // Compare cron pattern with current local time
    let time = Local::now();
    let matches_all = cron_all.is_time_matching(&time).unwrap();

    // Get next match
    let next = cron_all.find_next_occurrence(&time, false).unwrap();

    // Output results
    println!("Time is: {}", time);
    println!("Pattern \"{}\" does {} time {}", cron_all.pattern.to_string(), if matches_all { "match" } else { "not match" }, time );
    println!("Pattern \"{}\" will match next time at {}", cron_all.pattern.to_string(), next);

}

要匹配非本地时区,croner支持带有时区的chrono DateTime的 DateTime<Tz>。要使用命名时区,您可以使用 chrono-tz crate。

use croner::Cron;
use chrono::Local;
use chrono_tz::Tz;

fn main() {
    // Parse cron expression
    let cron = Cron::new("18 * * * 5")
      .parse()
      .expect("Couldn't parse cron string");

    // Choose a different time zone, for example America/New_York
    let est_timezone: Tz = "America/New_York".parse().expect("Invalid timezone");

    // Find the next occurrence in EST
    let time_est = Local::now().with_timezone(&est_timezone);
    let next_est = cron.find_next_occurrence(&time_est, false).unwrap();

    // Output results for EST
    println!("EST time is: {}", time_est);
    println!(
        "Pattern \"{}\" will match next time at (EST): {}",
        cron.pattern.to_string(),
        next_est
    );
}

此示例演示了如何计算下一个5个在星期五的除夕。我们将使用cron表达式匹配12月(12)的每个星期五(FRI),并使用 with_dom_and_dow 方法确保月份和星期几的条件都满足。

use croner::Cron;
use chrono::Local;

fn main() {
    // Parse cron expression for Fridays in December
    let cron = Cron::new("0 0 0 31 12 FRI")
      // Include seconds in pattern
      .with_seconds_optional()
      // Ensure both day of month and day of week conditions are met
      .with_dom_and_dow()
      .parse()
      .expect("Couldn't parse cron string");

    let time = Local::now();

    println!("Finding the next 5 New Year's Eves on a Friday:");
    for time in cron.iter_from(time).take(5) {
        println!("{}", time);
    }
}

模式

Croner使用的表达式与Vixie Cron非常相似,但增加了一些修改,如下所述

// ┌──────────────── (optional) second (0 - 59)
// │ ┌────────────── minute (0 - 59)
// │ │ ┌──────────── hour (0 - 23)
// │ │ │ ┌────────── day of month (1 - 31)
// │ │ │ │ ┌──────── month (1 - 12, JAN-DEC)
// │ │ │ │ │ ┌────── day of week (0 - 6, SUN-Mon)
// │ │ │ │ │ │       (0 to 6 are Sunday to Saturday; 7 is Sunday, the same as 0)
// │ │ │ │ │ │
// * * * * * *
  • Croner表达式有以下附加修饰符
    • ?:在croner的Rust版本中,问号的行为与*相同,以便可以使用旧版cron模式。
    • L:字母'L'可以用于月份中的天数字段,表示月的最后一天。当与#字符一起使用在星期几字段中时,表示该月的最后特定星期几。例如,5#L 表示该月的最后一个星期五。
    • #:#字符指定一个月中特定天次的“第N个”出现。例如,在星期几字段中提供 5#2 表示该月的第二个星期五。这可以与范围和天名结合使用。例如,MON-FRI#2 将匹配该月的第二周的星期一至星期五。
    • W:字符'W'用于在月份中的天数字段中指定与给定日期最接近的星期几。例如,15W将匹配该月最接近15号的星期几。如果指定的日期落在周末(星期六或星期日),则模式将匹配该日期之前或之后的最近工作日。例如,如果15号是星期六,15W将匹配14号(星期五),如果15号是星期日,它将匹配16号(星期一)。
字段 必需 允许的值 允许的特殊字符 备注
可选 0-59 * , - / ?
分钟 0-59 * , - / ?
小时 0-23 * , - / ?
月份中的天数 1-31 * , - / ? L W
月份 1-12 或 JAN-DEC * , - / ?
星期几 0-7 或 SUN-MON *, - / ? # L 0到6分别代表周日到周六
7是周日,与0相同
“#”用于指定星期的第几次出现

注意 星期和月份名称不区分大小写。无论是 MON 还是 mon 都可以使用。在周日期字段中使用 L 会影响所有指定的星期。例如,5-6#L 表示该月的最后一天星期五和星期六。"#”字符可以用来指定月份的“第几次”星期。例如,5#2表示该月的第二个星期五。

也可以使用以下“别名”作为模式。

别名 描述
@yearly 每年运行一次,即“0 0 1 1 *”。
@annually 每年运行一次,即“0 0 1 1 *”。
@monthly 每月运行一次,即“0 0 1 * *”。
@weekly 每周运行一次,即“0 0 * * 0”。
@daily 每天运行一次,即“0 0 * * *”。
@hourly 每小时运行一次,即“0 * * * *”。

配置

Croner提供了几种配置方法来更改模式的解释方式

1. with_seconds_optional()

此方法允许在cron模式中包含秒,但这不是强制性的。使用此方法,您可以创建包含或不包含秒字段的cron模式。这提供了更大的灵活性,允许进行更精确的调度,而无需在每个模式中定义秒的严格要求。

示例用法:

let cron = Cron::new("*/10 * * * * *") // Every 10 seconds
    .with_seconds_optional()
    .parse()
    .expect("Invalid cron pattern");

2. with_seconds_required()

with_seconds_optional() 相比,with_seconds_required() 方法要求每个cron模式中都包含秒字段。这强制了任务调度的高度精确性,确保每个模式都明确指定了任务应该运行的秒数。

示例用法:

let cron = Cron::new("5 */2 * * * *") // At 5 seconds past every 2 minutes
    .with_seconds_required()
    .parse()
    .expect("Invalid cron pattern");

3. with_dom_and_dow()

此方法允许在cron表达式中组合月份日期(DOM)和星期日期(DOW)条件。这对于需要月份和星期具体性的调度非常有用,例如,在一个月的第一天是星期一或圣诞节是星期五时运行任务。

示例用法:

let cron = Cron::new("0 0 25 * FRI") // When christmas day is on a friday
    .with_dom_and_dow()
    .parse()
    .expect("Invalid cron pattern");

4. with_alternative_weekdays()(Quartz模式)

此配置方法将星期模式从POSIX标准切换到Quartz风格的,通常用于基于Java的调度系统。对于那些习惯于Quartz指定星期方式或确保与现有Quartz调度兼容的人来说非常有用。

示例用法:

let cron = Cron::new("0 0 12 * * 6") // Every Friday (denoted with 6 in Quartz mode) at noon
    .with_alternative_weekdays()
    .parse()
    .expect("Invalid cron pattern");

文档

有关详细用法和API文档,请访问 docs.rs 上的 Croner

开发

要开始在Croner项目中开发

  1. 克隆仓库。
  2. 导航到项目目录。
  3. 使用 cargo build 构建项目。
  4. 使用 cargo test 运行测试。
  5. 使用 cargo run --example pattern_demo 运行演示

贡献

我们欢迎贡献!请随时提交一个拉取请求或打开一个问题。

许可证

本项目采用MIT许可证 - 详细内容请参阅LICENSE.md文件。

免责声明

请注意,Croner目前处于开发的早期阶段。因此,API在未来版本中可能会发生变化,遵循语义版本化原则。我们建议在将Croner集成到您的项目中时考虑这一点。

联系方式

如果您有任何问题或反馈,请在本仓库中打开一个问题,我们会尽快回复您。

依赖项

~1MB
~18K SLoC