Crontab 是 Linux 的定时任务调度工具,但它的时间表达式(如 */5 * * * *)对新手不够友好——"这到底什么时候会执行?" 这个项目用 Python 写一个命令行工具,输入 crontab 表达式,输出:人类可读的描述、接下来 N 次执行时间。
cron_parser.py,约 95 行先看效果:
$ python cron_parser.py '0 9 * * 1-5' 📅 表达式: 0 9 * * 1-5 📝 描述: 小时9 执行于 星期1到5 ⏰ 接下来 5 次执行时间: 1. 2026-08-07 09:00:00 周五 2. 2026-08-10 09:00:00 周一 3. 2026-08-11 09:00:00 周二 4. 2026-08-12 09:00:00 周三 5. 2026-08-13 09:00:00 周四
需要 Python 3.6+,以及装好 OpenCode(pip install opencode 或前往 opencode.ai 下载)。在你的项目目录下打开终端,运行 opencode 进入命令行模式,准备工作就完成了。
我对 OpenCode 说:
> 用 Python 写一个命令行工具,解析 crontab 表达式。输入 5 个字段(分 时 日 月 星期),分别解析每个字段。字段支持 *(通配)、1-5(范围)、1,3,5(列表)、*/5(步长)。最终生成一个 matches_time() 函数判断给定时间是否匹配。
OpenCode 生成了核心解析逻辑:
def parse_field(field: str, min_v: int, max_v: int) -> set:
values = set()
for part in field.split(','):
step = 1
if '/' in part:
part, step_s = part.split('/')
step = int(step_s)
if part == '*':
start, end = min_v, max_v
elif '-' in part:
a, b = part.split('-')
start, end = int(a), int(b)
else:
start = end = int(part)
for v in range(start, end + 1, step):
if min_v <= v <= max_v:
values.add(v)
return values
这里我没有手写解析逻辑,OpenCode 自动处理了逗号分隔、步长、范围三种语法的嵌套组合。一个提示词就搞定了最复杂的部分。
我对 OpenCode 说:
> 现在补充一个 next_runs 函数,计算从当前时间开始,接下来的 N 次执行时间。从当前分钟开始逐分钟递增,用 matches_time 检查是否匹配。
OpenCode 补充了:
def next_runs(expr: str, count: int = 5) -> list:
fields = parse_expression(expr)
dt = datetime.now().replace(second=0, microsecond=0) + timedelta(minutes=1)
runs = []
while len(runs) < count:
if matches_time(dt, fields):
runs.append(dt)
dt += timedelta(minutes=1)
return runs
这里有一个细节值得注意:我没有告诉 OpenCode"从下一分钟开始",但它自动加了 + timedelta(minutes=1)。对 crontab 工具来说,当前这一分钟如果已经过半,那本次执行就没意义了——这种边界条件的处理,OpenCode 帮你考虑到了。
我对 OpenCode 说:
> 帮我加一个 describe 函数,把 crontab 表达式翻译成中文描述。比如 */5 * * * * → "每5分钟",0 9 * * 1-5 → "小时9 星期1到5"。
OpenCode 生成了一组翻译函数:
def describe_field(field: str, name: str, lo: int, hi: int) -> str:
if field == '*':
return ''
parts = field.split(',')
desc_parts = []
for p in parts:
step = 1
if '/' in p:
p, step_s = p.split('/')
step = int(step_s)
if p == '*':
desc_parts.append(f'每{step}{name}')
elif '-' in p:
a, b = p.split('-')
desc_parts = f'{name}{a}到{b}' + (f'每{step}{name}' if step > 1 else '')
else:
desc_parts.append(f'{name}{p}')
return '、'.join(desc_parts)
OpenCode 能理解"翻译成中文描述"的意图,自动把字段名映射成"分钟""小时""星期"等中文,你不需要写映射表。
我对 OpenCode 说:
> 请补齐 main 函数和 CLI 入口。支持 -n 参数指定显示次数(默认 5),没有参数时显示帮助信息。输出要带 emoji 图标,让结果好看一些。
最终 main 函数:
def main():
args = sys.argv[1:]
count = 5
if '-n' in args:
idx = args.index('-n')
count = int(args[idx + 1])
del args[idx:idx + 2]
if not args:
print("Crontab 表达式解析工具\n")
print("用法: python cron_parser.py [-n N] 'crontab表达式'")
print("示例: python cron_parser.py '*/5 * * * *'")
print("示例: python cron_parser.py -n 10 '0 9 * * 1-5'")
sys.exit(0)
...
四个提示词,不到 4 分钟,一个完整可用的 crontab 解析工具就完成了。全程没有写一行循环或条件判断——你负责描述"要什么",OpenCode 负责"怎么做"。
#!/usr/bin/env python3
"""Crontab 表达式解析工具"""
import sys
from datetime import datetime, timedelta
FIELD_RANGES = {
'分钟': (0, 59), '小时': (0, 23), '日': (1, 31),
'月': (1, 12), '星期': (0, 6)
}
WEEKDAYS = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
def parse_field(field: str, min_v: int, max_v: int) -> set:
values = set()
for part in field.split(','):
step = 1
if '/' in part:
part, step_s = part.split('/')
step = int(step_s)
if part == '*':
start, end = min_v, max_v
elif '-' in part:
a, b = part.split('-')
start, end = int(a), int(b)
else:
start = end = int(part)
for v in range(start, end + 1, step):
if min_v <= v <= max_v:
values.add(v)
return values
def parse_expression(expr: str) -> list:
fields = expr.strip().split()
if len(fields) != 5:
raise ValueError("需要 5 个字段:分 时 日 月 星期")
result = []
for (name, (lo, hi)), val in zip(FIELD_RANGES.items(), fields):
result.append(parse_field(val, lo, hi))
return result
def matches_time(dt: datetime, fields: list) -> bool:
return (dt.minute in fields[0] and dt.hour in fields[1] and
dt.day in fields[2] and dt.month in fields[3] and
(dt.isoweekday() % 7) in fields[4])
def next_runs(expr: str, count: int = 5) -> list:
fields = parse_expression(expr)
dt = datetime.now().replace(second=0, microsecond=0) + timedelta(minutes=1)
runs = []
while len(runs) < count:
if matches_time(dt, fields):
runs.append(dt)
dt += timedelta(minutes=1)
return runs
def describe_field(field: str, name: str, lo: int, hi: int) -> str:
if field == '*':
return ''
desc_parts = []
for p in field.split(','):
step = 1
if '/' in p:
p, step_s = p.split('/')
step = int(step_s)
if p == '*':
desc_parts.append(f'每{step}{name}')
elif '-' in p:
a, b = p.split('-')
mid = f'{name}{a}到{b}'
desc_parts.append(f'{mid}每{step}{name}' if step > 1 else mid)
else:
desc_parts.append(f'{name}{p}')
return '、'.join(desc_parts)
def describe(expr: str) -> str:
fields = expr.strip().split()
if len(fields) != 5:
return '无效表达式'
descs = []
for (name, (lo, hi)), val in zip(FIELD_RANGES.items(), fields):
d = describe_field(val, name, lo, hi)
if d:
descs.append(d)
return ' 执行于 '.join(descs) if descs else '每分钟'
def main():
args = sys.argv[1:]
count = 5
if '-n' in args:
idx = args.index('-n')
count = int(args[idx + 1])
del args[idx:idx + 2]
if not args:
print("Crontab 表达式解析工具\n")
print("用法: python cron_parser.py [-n N] 'crontab表达式'")
print("示例: python cron_parser.py '*/5 * * * *'")
print("示例: python cron_parser.py -n 10 '0 9 * * 1-5'")
print("\n字段说明: 分钟(0-59) 小时(0-23) 日(1-31) 月(1-12) 星期(0-6,0=周日)")
sys.exit(0)
expr = args[0]
try:
print(f"📅 表达式: {expr}")
print(f"📝 描述: {describe(expr)}")
print(f"\n⏰ 接下来 {count} 次执行时间:")
for i, t in enumerate(next_runs(expr, count), 1):
print(f" {i:2}. {t.strftime('%Y-%m-%d %H:%M:%S')} {WEEKDAYS[t.isoweekday() % 7]}")
except ValueError as e:
print(f"错误: {e}")
sys.exit(1)
if __name__ == '__main__':
main()
这个 Crontab 解析工具开发过程不到 4 分钟,4 个自然语言指令,生成了 95 行完整可用代码。整个过程我做的事情只有三件:
描述需求 — 用自然语言说清楚要什么功能
逐层迭代 — 先骨架,再加计算,再加描述,最后补齐 CLI
直接运行 — 中间没有任何手动编码环节
对比传统开发方式:你需要查 Python datetime API 文档、手动处理 cron 字段的边界条件、自己写格式化输出——OpenCode 把这些机械性的工作全部接管,让你专注于定义"做什么",而非"怎么做"。对于这种小而精的 CLI 工具开发场景,效率提升是数量级的。