时间日期 · Cron / 调度

Cron 表达式

6/7 段表达式校验/解释/下次 N 次执行

本地处理 · 不上传 免费 · 无需登录 无次数限制 累计 64 次使用
5 段 · 标准 crontab
执行分布 · 今天
    就绪
    常用模板点击应用
    语法速查点击插入到光标字段 · 日与周同时限定时按标准 cron 取「或」
    第一节

    关于本工具

    About

    凌晨两点,运维盯着“0 0 2 * * ?”这个表达式,想确认它到底会不会在明天凌晨两点跑。全宝工具 Cron 表达式校验器,输入表达式即可实时校验合法性,逐段中文解释每个字段含义,并列出未来 N 次执行时间。所有解析在浏览器本地完成,表达式不上传服务器,无需担心敏感任务泄露。

    使用场景

    凌晨数据库备份

    运维值班的凌晨 2 点,需要写一条 cron 让服务器在每天凌晨 3 点 15 分执行数据库全量备份。手动写 `15 3 * * *` 总担心写反了分钟和小时的位置,或是漏掉了星期字段导致周末也跑。把表达式贴进工具,右侧立即给出人类可读的「每天 03:15」和下一次执行时间,确认无误后再部署到 crontab,不用再靠肉眼反复核对。

    定时清理日志文件

    应用日志每天增长 2GB,磁盘告警阈值是 85%。准备写一条 cron 在每周日凌晨 4 点删除 7 天前的 .log 文件。但 7 天前跨了月份边界,用 `0 4 * * 0` 只能保证周日执行,无法判断文件年龄。工具解析后发现这条表达式只在周日触发,于是改成 `0 4 * * 0` 配合脚本内的 find 命令,工具验证了「每周日 04:00」的语义,确保不会在周一凌晨误删。

    跨时区定时任务

    团队有台服务器在 UTC 时区,但业务需要在北京时间每天上午 9 点推送报表。手动把北京时间换算成 UTC 时间(凌晨 1 点)后写 `0 1 * * *`,工具解释为「每天 01:00」,但不确定是否包含夏令时影响。把表达式输入后,工具明确列出未来 5 次执行时间,全部落在凌晨 1 点整,排除夏令时偏移风险,直接复制到服务器。

    每月最后一天发工资条

    财务系统需要在每个月最后一天上午 10 点自动发送工资邮件。但「最后一天」在 cron 标准语法里没有直接表达,常见写法 `0 10 28-31 * *` 会在 2 月 28 日、30 日等非法日期也触发。把这条表达式贴进工具,工具列出 2025 年 2 月的执行日期,发现 2 月 28 日被触发,但 2 月 30 日不存在所以跳过,确认了这种「范围+跳过」的实际行为,才放心使用。

    双周例会提醒

    技术团队每两周的周三下午 3 点开复盘会,需要一条 cron 在会议前 15 分钟发钉钉提醒。尝试 `45 14 * * 3` 只能做到每周三,无法隔周执行。工具解析后发现该表达式是「每周三 14:45」,于是改为 `45 14 1-7,15-21 * 3`,工具验证出该表达式在每月 1-7 日和 15-21 日的周三触发,正好覆盖双周节奏,且不会在 8-14 日或 22-月末的周三误发。

    对比矩阵

    维度本工具竞品 A (crontab.guru)传统方法 (man crontab)
    隐私表达式解析在浏览器本地完成,不上传服务器解析在服务端完成,表达式会发送至其服务器完全离线,无网络依赖
    速度输入后即时反馈,无网络延迟依赖网络,响应速度受服务器负载影响需手动执行 crontab 命令或查阅文档,速度最慢
    离线可用支持离线使用,页面加载后断网仍可解析必须联网,断网无法使用完全离线
    学习成本提供中文解释与下次执行时间,零门槛英文界面,需理解英文术语需记忆 cron 语法与 man 手册,学习成本最高
    下次执行时间直接列出未来 N 次执行的具体日期时间仅显示下一次执行时间需手动计算或编写脚本推算
    表达式长度支持标准 5 段与 6 段(含秒)表达式仅支持标准 5 段支持任意段数,但需手动解析
    第二节

    使用指南

    Getting Started

    使用步骤

    1. 1在输入框键入 Cron 表达式(如 0 0 * * *),下方立即显示该表达式的可读解释与合法性校验结果
    2. 2点击「校验」按钮,若表达式无效则高亮错误位置并提示修正建议;若有效则显示绿色通过标记
    3. 3在「下次执行时间」区域设置起始时间与执行次数(如 5 次),点击「计算」后表格列出精确到秒的每次执行时间
    4. 4展开「表达式速查」面板,可点击预设模板(如「每天凌晨 2 点」)自动填充输入框并触发校验

    输入输出示例

    输入输出说明
    0 0 * * *每天 00:00 执行一次常规:最基础的每日定时任务,验证工具能否正确解析标准 5 段格式并输出中文描述
    */5 9-17 * * 1-5周一至周五 09:00-17:00 每 5 分钟执行一次常规:典型工作日轮询场景,验证步长(*/5)、范围(9-17)、星期(1-5)的组合解析
    0 0 1 1 *每年 1 月 1 日 00:00 执行一次边界:年任务,验证月份和日期同时指定时的逻辑,以及跨年边界(如 2 月 29 日)
    0 0 29 2 *每年 2 月 29 日 00:00 执行一次(仅闰年有效)边界:闰年特有日期,验证工具是否提示非闰年不触发,暴露日期合法性校验
    0 0 * * 0每周日 00:00 执行一次易错:星期字段 0 和 7 都表示周日,验证工具是否统一处理(部分实现只认 7)
    0 0 1 * 7每周日 00:00 执行一次(部分实现视为周日,部分视为周六)易错:7 在星期字段中含义有歧义(周日 vs 周六),验证工具是否明确标注或给出警告
    0 0 1 1 0每年 1 月 1 日且为周日时 00:00 执行一次易错:日期和星期同时指定时,逻辑为 AND(同时满足)而非 OR,验证工具是否正确解释

    常见错误对照

    1.星期字段同时用数字和英文缩写,导致冲突

    ✗ 错误0 0 * * 1,Mon
    ✓ 修复0 0 * * 1

    Cron 星期字段数字(0=周日)和英文缩写(MON)是同一语义的不同表示,混用会导致解析器重复匹配或报错,标准实现只接受一种表示。

    2.月份字段用 0 代替 1,导致表达式无效

    ✗ 错误0 0 1 0 *
    ✓ 修复0 0 1 1 *

    Cron 月份字段范围是 1-12(或 JAN-DEC),0 不在合法区间内,多数解析器直接拒绝执行,不会自动修正为 1 月。

    3.步长值超出字段范围,表达式静默失效

    ✗ 错误*/15 * * * *
    ✓ 修复*/15 * * * *

    步长值本身合法,但若步长与字段最大值不整除(如分钟 /15 在 0-59 内正常),问题出在用户误以为步长可跨天——实际上步长只在当前字段范围内循环。

    4.星期字段用 7 表示周日,但标准只认 0

    ✗ 错误0 0 * * 7
    ✓ 修复0 0 * * 0

    多数 Unix cron 实现中星期天用 0 表示,7 不被识别或视为非法值,部分解析器会报错而非自动转换。

    5.在分钟字段使用超过 59 的数值

    ✗ 错误60 0 * * *
    ✓ 修复0 0 * * *

    分钟字段合法范围是 0-59,60 超出边界,大多数解析器直接拒绝执行,不会自动截断或取模。

    6.误以为 L 表示最后一天,但标准 cron 无此语法

    ✗ 错误0 0 L * *
    ✓ 修复0 0 28-31 * *

    L 是 Quartz 调度器的扩展语法,标准 Unix cron 不支持。在标准 cron 中 L 会被当作普通字符导致表达式无效。

    7.逗号列表包含重复值,造成冗余匹配

    ✗ 错误0 0 * * 1,1,2
    ✓ 修复0 0 * * 1,2

    逗号列表中的重复值不会带来额外触发,但会增加解析开销,某些实现可能产生意外行为(如触发次数翻倍)。

    8.在星期字段使用 * 和具体值组合,语义混乱

    ✗ 错误0 0 * * 1-5,6
    ✓ 修复0 0 * * 1-5

    星期字段的 * 已表示所有天,再追加具体值会导致逻辑重复或冲突,部分解析器会忽略 * 或报错。

    第三节

    工作原理

    How It Works

    核心公式

    next_time = min{ t ∈ T | t > now ∧ match(t, cron_expr) }

    变量说明

    • now当前时间戳,精确到秒
    • cron_expr6/7 段 Cron 表达式字符串
    • T所有可能的时间点集合
    • match(t, expr)判断时间 t 是否满足表达式

    示例

    当前时间 2025-04-10 14:30:00,表达式 '30 15 * * 1-5'(周一到周五 15:30)。从 now 向后逐秒扫描:第一个满足的时间是 2025-04-10 15:30:00(当天周四),即 next_time = 2025-04-10 15:30:00。

    输入表达式拆分 6/7 段校验各字段查表转换(星期/月份)报错计算下次 N 次(纯浏览器内)展示结果(解释/时间)
    用户输入 / 报错 本地处理(校验/转换/计算) 输出结果
    第四节

    开发者集成

    For Developers

    6 种主流语言实现,复制即用:

    from croniter import croniter from datetime import datetime # 校验并获取接下来 5 次执行时间 cron_expr = "*/5 * * * *" # 每 5 分钟 base = datetime.now() cron = croniter(cron_expr, base) for i in range(5): print(cron.get_next(datetime)) # 下次执行时间
    const parser = require('cron-parser'); const interval = parser.parseExpression('0 9 * * 1-5'); // 工作日 9:00 for (let i = 0; i < 5; i++) { console.log(interval.next().toISOString()); // 下次执行时间 }
    package main import ( "fmt" "github.com/robfig/cron/v3" "time" ) func main() { expr := "0 0 1 * *" // 每月 1 日 0 点 schedule, _ := cron.ParseStandard(expr) now := time.Now() for i := 0; i < 5; i++ { next := schedule.Next(now) fmt.Println(next) now = next } }
    #!/bin/bash # 使用 crontab 内置语法校验(不实际安装) # 仅校验格式,不计算下次执行 cron_expr="30 4 * * 1" echo "$cron_expr" | crontab -i - 2>&1 || echo "格式无效"
    import com.cronutils.model.Cron; import com.cronutils.model.definition.CronDefinitionBuilder; import com.cronutils.model.time.ExecutionTime; import com.cronutils.parser.CronParser; import java.time.ZonedDateTime; public class CronNext { public static void main(String[] args) { String expr = "0 0/30 * * * ?"; // 每 30 分钟 CronParser parser = new CronParser(CronDefinitionBuilder.defineCron() .withSeconds().withMinutes().withHours().withDoM().withMonth().withDoW().instance()); Cron cron = parser.parse(expr); ExecutionTime exec = ExecutionTime.forCron(cron); ZonedDateTime now = ZonedDateTime.now(); for (int i = 0; i < 5; i++) { now = exec.nextExecution(now).get(); System.out.println(now); } } }
    <?php require 'vendor/autoload.php'; use Cron\CronExpression; $cron = CronExpression::factory('0 0 * * 0'); // 每周日 0 点 $nextRun = $cron->getNextRunDate('now', 0, true); // 下次执行 for ($i = 0; $i < 5; $i++) { echo $nextRun->format('Y-m-d H:i:s') . "\n"; $nextRun = $cron->getNextRunDate($nextRun, 1, true); }
    第五节

    常见问题

    Q & A
    我输入了一个 cron 表达式,但点校验没反应,是哪里不对?

    最常见的原因是格式错误,比如用了中文逗号或空格数不对。标准 cron 是 5 段(分 时 日 月 周),6 段(加秒)或 7 段(加年)也支持,但段数必须严格匹配。本工具在输入框下方会实时提示当前段数和格式状态,如果完全没反应,先检查是否混入了全角符号或多余空格。另外,浏览器控制台如果有报错,可能是脚本加载问题,刷新页面重试即可。

    为什么我写 '0 0 1 * *' 它说下个月 1 号执行,但我觉得应该是今天?

    cron 表达式的日期字段(第 3 位)是「几号」,不是「几天后」。'0 0 1 * *' 意思是「每月 1 号 0 点 0 分」,工具会从当前时间往后找最近一次满足条件的时刻。如果今天不是 1 号,它自然跳到下个月 1 号。如果你想要「每隔 1 天执行一次」,应该用 '0 0 */1 * *' 或 '0 0 * * *'(每天),而不是用 '1' 这个数字。

    这个工具校验 cron 表达式的规则跟 Linux 系统里的 cron 一样吗?

    本工具遵循标准的 POSIX cron 规则,与 Linux crontab 的 5 段格式完全兼容。但它额外支持 6 段(秒)和 7 段(年)的非标准扩展,这些在原生 Linux cron 中不识别。另外,工具在解释时会把星期字段(第 5 位)的 0 和 7 都视为周日,这与多数 Linux 实现一致。如果你的表达式在服务器上跑正常但工具报错,大概率是段数不一致——检查你系统里用的是否是 5 段标准版。

    周和日都写了值,比如 '0 0 1 * 5',它到底哪天执行?

    当第 3 位(日)和第 5 位(周)同时指定非 * 值时,标准 cron 行为是「两个条件满足任意一个就执行」,即「每月 1 号或者每周五都执行」。但某些实现(如 Quartz)会要求两者同时满足。本工具默认采用标准 UNIX 逻辑(或关系),并在表达式解释结果里明确标出「匹配条件:日 OR 周」。如果你需要严格同时满足,建议只用其中一个字段,另一个写 *。

    我设了一个每小时执行一次的表达式,但算出来的下次执行时间跟预期差了一个小时,怎么回事?

    检查是否跨了夏令时切换日。cron 基于系统时钟,如果时区有夏令时,每年 3 月和 11 月某天会「少一小时」或「多一小时」。本工具在计算下次执行时使用的是用户浏览器本地时区,如果浏览器自动应用了夏令时,结果就会「跳」或「重复」一小时。解决方案:在工具结果区查看时区标注,确认是否启用了夏令时调整。如果任务必须固定 UTC 时间,建议用 0 时区(UTC)的表达式。

    这个工具是纯前端算的吗?我的 cron 表达式会不会被传到服务器?

    是的,完全在浏览器本地计算,不发送任何网络请求。表达式的校验、解释和下次 N 次执行时间推算全部由前端 JavaScript 完成。可以断网测试——关闭 Wi-Fi 后刷新页面,工具仍然可以正常使用。这意味着即使表达式包含敏感信息(比如任务名中含业务关键词),也不会离开本机。所有计算结果都只存在当前页面内存中,刷新即消失。

    我写了 '*/5 * * * *' 但工具说每 5 分钟执行一次,为什么不是每 5 秒?

    标准 cron 第一段是分钟,不是秒。'*/5 * * * *' 表示「每 5 分钟」,具体是 0、5、10……55 分执行,不是每 5 秒。如果你需要每 5 秒执行一次,必须用 6 段格式,例如 '*/5 * * * * *'(第一段是秒)。本工具会根据你输入的段数自动识别格式,并在解释结果开头写明「共 X 段,已按 XX 格式解析」。如果误用了 5 段写秒,工具会直接报段数错误。

    L、W、# 这些特殊字符支持吗?我写的 '15W' 报错了。

    本工具支持标准的数字、星号、逗号、连字符、斜杠(枚举、范围、步长)以及问号(?)用于周/日字段的互斥占位。但 L(最后一天/最后一个周几)、W(最近工作日)、#(第几个周几)属于 Quartz 调度器的扩展语法,非 POSIX 标准,本工具目前不支持。如果你的调度系统是 Quartz(如 Java 项目),建议改用其他专为 Quartz 设计的 cron 工具。

    隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。

    选择 打开 +新窗口 esc关闭