跳转到内容
Tutorial

通过 REST API 解析和验证 cron 表达式

| 4 min read

使用 Botoi cron 解析器 API 验证 cron 表达式、生成人类可读的描述并预览即将到来的运行。 在几分钟内为您的管理面板构建一个 cron 预览小部件。

Clock gears and scheduling calendar
Photo by Lukas Blazek on Unsplash

您正在构建一个管理面板,用户可以在其中安排定期作业。 他们输入一个 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 并返回错误 给用户的消息。 您还可以存储 descriptionnextRun 与数据库中的原始表达式一起显示,因此您可以在列表视图中显示它们,而无需 再次调用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 端点,涵盖查询、文本处理、图片生成和开发者工具。免费套餐,无需信用卡。