通过 REST API 解析和验证 cron 表达式
使用 Botoi cron 解析器 API 验证 cron 表达式、生成人类可读的描述并预览即将到来的运行。 在几分钟内为您的管理面板构建一个 cron 预览小部件。
您正在构建一个管理面板,用户可以在其中安排定期作业。 他们输入一个 cron 表达式
进入文本字段,点击保存,然后期望系统做正确的事情。 问题:cron 语法
是神秘的。 */15 * * * * 已经很清楚了,但是呢 0 9 1-15 * 1-5?
大多数用户(以及许多开发人员)无法一眼读懂它。
您需要在用户保存表达之前*向他们展示其表达的含义。 像这样的描述 “星期一到星期五,第 1 到 15 天的 09:00”比工具提示链接更有价值 到 crontab.guru。
Botoi 的 cron 解析器 API 在单个 POST 请求中执行三件事:验证表达式、 生成人类可读的描述,并返回下一个计划的运行时间。 没有计划任务 要安装的库,无需维护解析逻辑。
解析端点
发送 cron 表达式到 /v1/cron/parse 并得到结构化的分解。
curl -X POST https://api.botoi.com/v1/cron/parse \\
-H "Content-Type: application/json" \\
-d '{"expression": "*/15 * * * *"}'
回复:
{
"success": true,
"data": {
"isValid": true,
"description": "Every 15 minutes",
"nextRuns": [
"2026-03-26T18:30:00Z",
"2026-03-26T18:45:00Z",
"2026-03-26T19:00:00Z",
"2026-03-26T19:15:00Z",
"2026-03-26T19:30:00Z"
],
"parts": {
"minute": "*/15",
"hour": "*",
"dayOfMonth": "*",
"month": "*",
"dayOfWeek": "*"
}
}
}
响应包括您需要的一切: isValid 旗帜,简单的英语
description、UTC 中接下来的五个运行时间以及各个 parts
按字段细分。 您可以直接在 UI 中显示描述并使用
nextRuns 数组以显示即将执行的预览。
获取更多即将举行的跑步活动
如果您需要五个以上的预览日期,或者您只关心时间表而不关心具体时间
描述,使用 /v1/cron/next 端点。 通过一个 count 参数
控制您返回的未来运行时间。
curl -X POST https://api.botoi.com/v1/cron/next \\
-H "Content-Type: application/json" \\
-d '{"expression": "0 9 * * MON-FRI", "count": 5}'
回复:
{
"success": true,
"data": {
"nextRuns": [
"2026-03-27T09:00:00Z",
"2026-03-30T09:00:00Z",
"2026-03-31T09:00:00Z",
"2026-04-01T09:00:00Z",
"2026-04-02T09:00:00Z"
]
}
}
请注意 3 月 27 日(星期五)和 3 月 30 日(星期一)之间的时间间隔。 表达式
0 9 * * MON-FRI 跳过周末,API 正确反映了这一点。
构建 cron 预览小部件
以下是如何将解析端点连接到前端输入字段。 当用户输入 cron 时 表达,小部件调用 API 并实时显示描述和即将运行的运行。
async function parseCron(expression) {
const res = await fetch("https://api.botoi.com/v1/cron/parse", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ expression }),
});
return res.json();
}
// Example: user types "0 9 * * MON-FRI" into a text input
const input = document.querySelector("#cron-input");
const preview = document.querySelector("#cron-preview");
input.addEventListener("input", async (e) => {
const { data } = await parseCron(e.target.value);
if (data.isValid) {
preview.innerHTML = \`
<p class="text-green-600">\\\${data.description}</p>
<ul>
\\\${data.nextRuns
.map((run) => \`<li>\\\${new Date(run).toLocaleString()}</li>\`)
.join("")}
</ul>
\
对于生产用途,请添加防抖(200-300 毫秒),这样您就不会在每次击键时触发请求。 API 在 Cloudflare 边缘的响应时间不到 50 毫秒,因此预览感觉是即时的 请求出去。
反应/预反应版本
如果您使用的是 React 或 Preact,这里有一个组件,它用一个包装了相同的逻辑
AbortController 取消过时的请求。
import { useState, useEffect } from "react";
function CronPreview({ value }) {
const [result, setResult] = useState(null);
useEffect(() => {
if (!value.trim()) {
setResult(null);
return;
}
const controller = new AbortController();
fetch("https://api.botoi.com/v1/cron/parse", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ expression: value }),
signal: controller.signal,
})
.then((r) => r.json())
.then(({ data }) => setResult(data))
.catch(() => {});
return () => controller.abort();
}, [value]);
if (!result) return null;
if (!result.isValid) {
return <p className="text-red-600">Invalid expression</p>;
}
return (
<div>
<p className="font-medium">{result.description}</p>
<p className="text-sm text-gray-500 mt-1">
Next run: {new Date(result.nextRuns[0]).toLocaleString()}
</p>
</div>
);
}
保存前验证用户输入
客户端预览对于用户体验来说非常有用,但您还应该先在服务器上进行验证
坚持 cron 作业。 从后端调用解析端点并检查
isValid 旗帜。
async function saveCronJob(name, expression) {
// Validate the expression before saving
const res = await fetch("https://api.botoi.com/v1/cron/parse", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ expression }),
});
const { data } = await res.json();
if (!data.isValid) {
throw new Error("Invalid cron expression: " + expression);
}
// Save to your database with the parsed metadata
await db.cronJobs.create({
name,
expression,
description: data.description,
nextRun: data.nextRuns[0],
});
return { description: data.description, nextRun: data.nextRuns[0] };
}
当用户提交无效表达式时,API 会返回一个干净的响应,您可以采取行动:
{
"success": true,
"data": {
"isValid": false,
"description": null,
"nextRuns": [],
"parts": null
}
}
无需捕获异常,无需编写正则表达式。 查看 data.isValid 并返回错误
给用户的消息。 您还可以存储 description 和 nextRun
与数据库中的原始表达式一起显示,因此您可以在列表视图中显示它们,而无需
再次调用API。
常见的 cron 表达式以及 API 返回的内容
| 表达 | 描述 |
|---|---|
* * * * * |
每分钟 |
*/15 * * * * |
每15分钟一班 |
0 * * * * |
每小时 |
0 9 * * MON-FRI |
周一至周五 09:00 |
0 0 1 * * |
每月 1 日午夜 |
30 4 * * SUN |
周日 04:30 |
0 9,17 * * * |
每天 09:00 和 17:00 |
0 0 * * 0 |
周日午夜 |
这些表达式中的每一个都返回相同的结构化响应:有效性标志、描述、 接下来运行,并解析部分。 您可以在集成 API 时使用上表作为测试用例。
为什么将 cron 解析卸载到 API 上?
- 没有库依赖。 每种语言都存在 Cron 解析库,但是 他们添加包大小(前端)或依赖项维护(后端)。 单个 HTTP 调用取代 图书馆。
- 跨服务的一致行为。 如果您的系统有 Node.js 调度程序, Python Worker 和 Go 微服务,它们解析 cron 表达式的方式都不同。 一个API 为您提供单一事实来源。
- 免费的人类可读的描述。 从 cron 生成自然语言 语法比解析时间表更难。 API 在一次调用中处理这两个问题。
- 用户即时预览。 低于 50 毫秒的边缘响应进行实时验证 实用,甚至在每次击键时都具有防抖功能。
FAQ
- cron 解析器 API 是否支持 @daily 或 @weekly 等非标准表达式?
- 是的。 解析端点接受标准的五字段 cron 表达式和常见的速记别名,例如 @yearly、@monthly、@weekly、@daily 和 @hourly。 响应将它们标准化为标准的五字段格式。
- nextRuns 时间戳位于哪个时区?
- 响应中的所有时间戳均采用 UTC(ISO 8601 格式)。 使用 Intl.DateTimeFormat 或 date-fns 等库将它们转换为客户端的用户本地时区。
- 我可以请求的下次运行次数是否有限制?
- /v1/cron/next 端点接受计数参数。 您可以在一次调用中请求最多 100 个即将到来的运行时间。 如果省略该参数,则默认值为 5。
- 我需要 API 密钥才能使用 cron 解析器吗?
- 不需要。匿名访问的速度为每分钟 5 个请求,并具有基于 IP 的速率限制。 为了获得更高的吞吐量,请在 botoi.com/api 上注册 API 密钥。
- 我可以在 cron 表达式中使用 MON-FRI 等日期名称吗?
- 是的。 解析器支持相应字段中的三字母日缩写(SUN、MON、TUE、WED、THU、FRI、SAT)和月份缩写(JAN 到 DEC)。
开始使用 botoi 构建
150+ 个 API 端点,涵盖查询、文本处理、图片生成和开发者工具。免费套餐,无需信用卡。