Crontab中文表达式解析

Cron表达式深度解析:从语法到实战的完整指南 任务调度是自动化运维和系统开发中的核心基础概念,它通过预定义的时间规则自动触发特定操作,从而提升系统效率和可靠性。其原理在于将时间维度拆解为多个字段(如分、时、日),并通过一套特殊的语法符号(如*、/、-)进行灵活组合,以精确描述复杂的执行周期。这项技术的核心价值在于实现程序化、无人值守的定时任务执行,是构建可靠后台服务、数据批处理以及自动化运维体系的基石。在实际应用中,它广泛服务于数据备份、报表生成、缓存清理和监控报警等关键业务场景。本文聚焦于任务调度的通用实现工具——Cron表达式,深入剖析其在不同系统 阅读详情

简介

最近工作中在使用调度框架,经常和定时表达式打交道,并且有查看表达式中文解释的需求,于是在网上搜集资料和自己进行一定的修改,写了一个Crontab表达式解析的工具类

详解

这个没啥好解释,看资料,自己试着动手写写,看看运行时间示例是否和自己想象的一样,就差不多了

不多说,直接上代码:

package com.ninetech.cloud.bw.rpa.util;

import org.springframework.scheduling.support.CronSequenceGenerator;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * crontab 工具类
 */
public class CrontabUtils {

    /**
     * 需要展示的表达式时间条数
     */
    private final static int size = 10;
    private static final String common = "*";
    private static final String questionMark = "?";
    private static final String hyphen = "-";
    private static final String slash = "/";
    private static final String comma = ",";
    private static final String second = "秒";
    private static final String minute = "分";
    private static final String hour = "时";
    private static final String day = "日";
    private static final String week = "周";
    private static final String month = "月";

    public static String parse(String crontab) {
        try {
            StringBuilder result = new StringBuilder("表达式:").append(crontab).append("\n");
            result.append(translateToChinese(crontab)).append("\n");
            result.append("\n").append("表达式执行时间列表示例:").append("\n");
            for (String exampleTime : examples(crontab)) {
                result.append(exampleTime).append("\n");
            }
            return result.toString();
        } catch (Exception e) {
            return "无Crontab表达式";
        }
    }

    private static List<String> examples(String crontab) {
        final CronSequenceGenerator generator = new CronSequenceGenerator(crontab);
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<String> res = new ArrayList<>(size);
        for (int i = 0; i < size; i++) {
            date = generator.next(date);
            res.add(sdf.format(date));
        }
        return res;
    }

    public static String translateToChinese(String cronExp) {
        String[] tmpCorns = cronExp.split(" ");
        StringBuffer sBuffer = new StringBuffer();
        if (tmpCorns.length != 6) {
            throw new RuntimeException("请补全表达式,必须标准的cron表达式才能解析");
        }
        // 解析月
        descMonth(tmpCorns[4], sBuffer);
        // 解析周
        descWeek(tmpCorns[5], sBuffer);
        // 解析日
        descDay(tmpCorns[3], sBuffer);
        // 解析时
        descHour(tmpCorns[2], sBuffer);
        // 解析分
        descMinute(tmpCorns[1], sBuffer);
        // 解析秒
        descSecond(tmpCorns[0], sBuffer);
        return sBuffer.toString();
    }

    private static void descSecond(String s, StringBuffer sBuffer) {
        desc(s, sBuffer, second);
    }

    private static void descMinute(String s, StringBuffer sBuffer) {
        desc(s, sBuffer, minute);
    }

    private static void descHour(String s, StringBuffer sBuffer) {
        desc(s, sBuffer, hour);
    }

    private static void descDay(String s, StringBuffer sBuffer) {
        desc(s, sBuffer, day);
    }

    private static void descWeek(String s, StringBuffer sBuffer) {
        desc(s, sBuffer, week);
    }

    private static void descMonth(String s, StringBuffer sBuffer) {
        desc(s, sBuffer, month);
    }

    private static void desc(String s, StringBuffer sBuffer, String flag) {
        if (s.equals("1/1")) {
            s="*";
        }
        if (s.equals("0/0")) {
            s="0";
        }
        if (common.equals(s)) {
            if (flag.equals(week)) {
                sBuffer.append("每").append(turnWeek(s));
            } else {
                sBuffer.append("每").append(flag);
            }
            return;
        }
        if (questionMark.equals(s)) {
            return ;
        }
        if (s.contains(comma)) {
            String[] arr = s.split(comma);
            for (String value : arr) {
                if (value.length() != 0) {
                    if (flag.equals(week)) {
                        sBuffer.append(turnWeek(value)).append("和");
                    } else {
                        sBuffer.append("第").append(value).append(flag).append("和");
                    }
                }
            }
            sBuffer.deleteCharAt(sBuffer.length()-1);
            sBuffer.append("的");
            return;
        }

        if (s.contains(hyphen)) {
            String[] arr = s.split(hyphen);
            if (arr.length!=2) {
                throw new RuntimeException("表达式错误"+s);
            }
            if (flag.equals(week)) {
                sBuffer.append(turnWeek(arr[0])).append(turnWeek(arr[1]));
            } else {
                sBuffer.append("从第").append(arr[0]).append(flag).append("到第").append(arr[1]).append(flag);
            }
            return;
        }

        if (s.contains(slash)) {
            String[] arr = s.split(slash);
            if (arr.length!=2) {
                throw new RuntimeException("表达式错误"+s);
            }
            if (arr[0].equals(arr[1])||arr[0].equals("0")) {
                sBuffer.append("每").append(arr[1]).append(flag);
            }else {
                sBuffer.append("每").append(arr[1]).append(flag).append("的第").append(arr[0]).append(flag);
            }
            return;
        }

        if (flag.equals(week)) {
            sBuffer.append("每").append(turnWeek(s));
        } else {
            sBuffer.append("第").append(s).append(flag);
        }
    }

    private static String turnWeek(String week){
        switch (week) {
        case "0":
            return"周天";
        case "1":
            return"周一";
        case "2":
            return"周二";
        case "3":
            return"周三";
        case "4":
            return"周四";
        case "5":
            return"周五";
        case "6":
            return"周六";
        case "7":
            return"周日";
        default:
            return null;
        }
    }

    public static void main(String[] args) {
        for (String s : parse("0/10 3/5 1-3 * 1 0").split("\n")) {
            System.out.println(s);
        }
    }
}

执行的结果如下:

表达式:0/10 3/5 1-3 * 1 0
第1月每周天每日从第1时到第3时每5分的第3分每10秒

表达式执行时间列表示例:
2022-01-02 01:03:00
2022-01-02 01:03:10
2022-01-02 01:03:20
2022-01-02 01:03:30
2022-01-02 01:03:40
2022-01-02 01:03:50
2022-01-02 01:08:00
2022-01-02 01:08:10
2022-01-02 01:08:20
2022-01-02 01:08:30

参考链接

Ubuntu Cron 深度解析:原理、陷阱与高可靠配置实践 Cron 是 Linux 系统中最基础也最易被误用的定时任务调度机制,其本质是事件驱动的守护进程,依赖严格的时间表达式语法、隔离的执行环境和明确的权限上下文。理解 cron 的五字段规则、PATH 环境缺失、shell 差异(dash vs bash)及日志重定向陷阱,是保障自动化稳定运行的前提。它广泛应用于系统监控、日志轮转、备份清理等运维场景,也是 DevOps 流水线中定时触发环节的关键底座。本文聚焦 Ubuntu 系统(20.04/22.04/24.04 LTS)下的真实运作机制,深入剖析 cron 阅读详情

相关推荐

银河麒麟V10 SP2上,Crontab定时任务配置保姆级教程(附日志排查技巧)

本文提供银河麒麟V10 SP2系统上Crontab定时任务的完整配置指南,包括基础设置、实战案例和日志排查技巧。特别针对国产化环境中的路径规范、权限管理等问题给出解决方案,帮助运维人员高效实现系统自动化任务管理。

weixin_30410119的博客 303

将cron表达式解析成中文,方便客户理解

/** * 描述 * * @author Norton Lai * @created 2019-2-27 下午4:54:36 */ public class Test { static final String xin="*"; static final String wenhao="?"; static final String dao="-"; ...

PiaoMiaoXiaodao的博客 4935

软考中级信息系统监理师(第二版)-第21章基础设施工程监理

由于网络信息技术的飞速发展,变化日新月异,网络设计不但要保证目前网络传输容量的要求,也要考虑今后网络的发展,满足当前以及今后相当一段时间内的网络需求,便于向新技术的升级和衔接,同时又需要保护原有的投资。通用布缆系统工程中,承建单位的竣工文档主要包括以下内容:承建合同,招标文件,投标文件,设计方案,工程实施组织设计方案,工程施工报告,隐蔽工程记录,变更记录,自测报告,信息点分布图(表),园区、楼宇、水平配线表,楼层平面图及无线设备点位图,无线设备信息表,竣工图纸等。多排安装时,列间距不应小于1200mm。

2301_78583973的博客 1400

在线常用crontab表达式大全验证解析

在线常用crontab表达式大全验证解析 在线常用crontab表达式大全验证解析 本工具可以在线模拟Crontab表达式的执行时间并且收集整理了常用的Crontab表达式。 本工具可以在线模拟Crontab表达式的执行时间并且收集整理了常用的Crontab表达式。 https://tooltt.com/crontab/ ...

Linux,Java,SpringBoot,Python,Lua略知一点 2161

别急着做AI:FDE教你识别真需求,让AI真正落地

人工智能项目在落地过程中,经常出现业务方高喊“我们要做AI”,却说不清具体应用场景的现象。判断一个需求是否值得用AI实现,不能只看技术流行度,而要从问题出现频率、当前替代方案以及可量化业务价值三个维度展开验证。同时需要冷静比较规则引擎与大模型的边界:不是所有语义任务都要靠生成式模型,稳定、可解释且低成本的传统方案往往更具工程性价比。数据闭环也至关重要,缺乏历史样本与反馈回流路径的项目,很难在真实环境中持续优化。针对智能客服、合同审查或企业知识库等典型场景,可借助人机协同与最小代价的用户验证,逐步筛除伪需求,

weixin_42624889的博客 341

LTE信令流程——切换

LTE信令流程 切换 切换是由基站发起的,不同于小区重选,小区重选是由UE发起的。 基站利用移动性管理算法给UE下发测量任务,在RRC重配置消息中携带MeasConfig信元给UE下发测量配置 切换有三种场景: 同一基站内不同小区的切换 不同基站间基于X2的切换(MME不变) 不同基站间基于S1的切换(MME/SGW可能改变) 1. 同一基站内不同小区的切换 连接态的UE在一个基站的不同小区之间移动 UE上报合适的测量报告(Measure Reports),触发基站切换 基站下发切换命令给UE,

Hxx的博客 1万+

Python:正确解析crontab表达式

不用传递参数,使用默认行为,可以正确拆分出5个值,而使用了单空格拆分,由于用户可能会输入多个空格分隔,从而解析错误。使用Python解析crontab表达式的时候,

彭世瑜的博客 905

IP2315高效同步降压充电IC在快充应用中的硬件与软件控制策略

本文深入解析IP2315高效同步降压充电IC在快充应用中的硬件与软件控制策略,涵盖其核心特性、硬件电阻调节技巧、I2C动态控制方案、散热设计优化及典型问题排查。IP2315支持多种快充协议,如Type-C PD、华为FCP等,适用于便携设备快速充电需求,并通过I2C实现灵活的充电参数设置,提升充电效率与安全性。

weixin_29248313的博客 538

JAVA cron转中文

sBuffer.append(getPeriod(tmpCorns[3], "日"));sBuffer.append(getPeriod(tmpCorns[2], "时"));sBuffer.append(getPeriod(tmpCorns[1], "分"));sBuffer.append(getPeriod(tmpCorns[0], "秒"));stringBuffer.append("每").append(period);sBuffer.append("星期天");

hbzslb的博客 840

学Simulink——基于AI融合与智能调度的场实例:联邦学习支持的多卫星协同通信建模

本文介绍了一种基于联邦学习的多卫星协同通信Simulink建模方法。系统采用"星-星协同+星-地协调"架构,每颗卫星本地训练LSTM链路预测模型,地面中心通过FedAvg算法聚合模型参数。建模过程包括卫星通信模型构建、联邦学习机制设计、协同决策系统开发等步骤,支持隐私保护、高效协同和智能决策。仿真结果表明,该方法在预测准确率(89%)、吞吐量(56.7Mbps)等方面优于独立训练模式,接近集中式训练性能。该方案为大规模卫星星座的智能协同提供了仿真验证平台,未来可拓展去中心化联邦学习、异构

xiaoheshang_123的博客 209

【模型实战】MiMo-VL-7B讲解与实战

维度成绩MMMU70.6(图像理解最难测试之一)VideoMME70.8(视频理解标杆)59.4(超越78B参数模型)56.1(超过专用GUI模型)Elo评分开源VLM排名第一(7B~72B)社区热度过去一个月下载超1,600次(RL+SFT)📌一句话概括MiMo-VL 是目前性能最强、推理最稳、体验最佳、生态最全的7B级开源视觉语言模型。

m0_47867638的博客 1195

SpringBoot>16 - 使用 @Scheduled 实现定时任务

简介: 实现定时任务的方式很多,基于JDK的Timer、Quartz等等,本章介绍 SpringBoot1.5 中Spring Task实现定时任务,非常方便。 项目构建: springboot web项目构建完就默认内置了@Scheduled 定时任务。 1、开启定时支持,在启动类上添加注解@EnableScheduling // mapper 接口类扫描包配置 @MapperScan(&amp;amp;amp;amp;quot;...

cp026la的博客 990

多目标优化AI Agent:增强LLM的复杂决策能力

在人工智能领域,尤其是自然语言处理(NLP)和大语言模型(LLM)的应用中,决策问题往往涉及多个目标的平衡与优化。例如,在智能客服系统中,既要提高客户满意度,又要降低运营成本;在自动驾驶中,既要确保安全,又要追求行驶效率。传统的单目标优化方法难以满足这种复杂场景的需求,因此多目标优化成为了一种必然趋势。AI Agent是一种智能系统,能够通过感知环境、处理信息并采取行动来实现特定目标。它可以是一个软件程序,也可以是一个物理设备。NSGA-II:一种基于群体的多目标优化算法,通过遗传算法的思想进行迭代优化。

AI天才研究院 1299

crontab表达式

Linux下面的crontab表达式是一个很神奇的表达式,几乎所有有意义的时间都能表示出来,最近由于某些原因,也对这个学习了一下。 * * * * * commond 前面的五个星号分别表示 分 时 日 月 周,commond表示你要操作的命令 分(1-59)(*或*/1表示每分钟) 时(1-23)(0表示0点) 日(1-31) 月(1-12) 周(1-6)(0表示周日) 使用方式...

weixin_30408675的博客 118

YOLOv13添加轻量化的EMA模块Faster_EMA,轻量又涨点!map50提升4.56个点,召回率提升9.66!

本文介绍了YOLOv13模型的优化移植方法,通过添加Faster_EMA模块和超参数调整,使模型性能显著提升。主要修改包括:1) 创建新的模型配置文件yolov13-Faster_EMA.yaml;2) 在tasks.py中添加新模块;3) 修改__init__.py和block.py文件,新增Partial_conv3和DropPath类。优化后模型mAP50提升4.56%,召回率提升9.66%,验证了改进方案的有效性。代码实现了局部卷积和随机深度等先进技术,为YOLO系列模型性能优化提供了新思路。

FJN110的博客 2604

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Django项目定时任务--django-crontab

Django项目设置定时任务以及django-crontab的使用

YUE 5051

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Cron表达式工具实战:双规格校验与时间预览全解析

在定时任务开发中,Cron表达式是连接业务需求与调度框架的关键语法。无论是Linux的5位Crontab写法,还是Java生态中Quartz和Spring @Scheduled的6位格式,字段含义与符号差异常常导致校验通过却运行报错的困境。理解表达式求值的基础原理,掌握字段映射和解析逻辑,是高效使用定时任务的前提。本文从表达式的基本概念与解析原理出发,介绍一个同时兼容双规格的高频工具,它提供未来执行时间预览和常用预设,能直观验证表达式语义,帮助开发者在业务调度、前端组件集成以及运维排查中快速定位问题。将表达

weixin_34050519的博客 385

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

AI自动生成crontab任务:告别手动配置的繁琐

对于需要长期运行的任务管理场景,平台的一键部署功能也很实用,生成的脚本可以直接部署到测试环境验证。这种从描述到落地的闭环体验,特别适合需要频繁调整定时任务的运维工作。最近我发现用AI辅助生成crontab任务可以大幅简化这个过程,下面分享我的实践心得。测试时,发现其AI对话区能直接理解"每周工作日早上8点发提醒"这样的需求,自动生成正确的表达式和解释说明,整个过程不需要记忆任何语法规则。在Linux系统管理中,crontab是定时执行任务的利器,但它的语法规则对新手来说并不友好。

BlackironLynx23的博客 396

Ubuntu 定时运行命令脚本crontab

crontab的时间表达式 基本格式 : *  *  *  *  *  command 分  时  日  月  周  命令 下面看几个例子: 1、每分钟执行一次 * * * * * 2、每隔一小时执行一次 00 * * * * 3、每小时的15和30分各执行一次 15,45 * * * * (,表示并列) 4、在每天上午 8...

huang.xiao的专栏 1239

Cron 表达式字段规则与在线解析:5 位 6 位 7 位都怎么写

梳理 Cron 表达式 5/6/7 位字段规则,记录日和周冲突、步长边界、框架差异三个常见踩坑点,并用在线解析工具验证。

weixin_42362781的博客 180

如何做出永不断播的虚拟人视频:MuseV、MuseTalk、MusePose 三件套完整实操指南

想打造一个会说话、会摆动作、连续播几个小时都不崩的虚拟人?MuseV(负责生成视频)、MuseTalk(负责口型)、MusePose(负责肢体动作)这三件套就是为这件事准备的。无论你是做虚拟主播的内容创作者,还是想落地数字人功能的开发者,读完后你手里会有一条完整可跑通的虚拟人生成流水线。 ## 一分钟看懂三个组件:管视频、管嘴、管身体 三个组件的分工可以压成一句话——MuseV 出画面,Mus

gitblog_00789的博客 402

SpringBoot - 集成Quartz框架之CRON表达式

CRON表达式是一个字符串,字符串由5个或6个空格隔开,分为6个或7个域,每一个域代表一个含义,表达如如下:秒 分 时 日 月 周 年[可选]。

记录并分享 1531

Ubuntu下Apache2+HTTPS+s-nail+crontab运维闭环

在服务器运维中,Web 服务、传输加密、告警通知与定时调度构成最常见的基础设施闭环。Apache2 承担 HTTP/HTTPS 站点与虚拟主机管理,HTTPS 依托 SSL/TLS 证书完成加密、身份校验与 301 跳转;s-nail 通过外部 SMTP 把证书到期、磁盘告警等信号送出;crontab 依据时间表达式触发巡检、续期和清理脚本。它们组合后,价值不只是自动化,更在于让证书续期后重载、静默退信、PATH 缺失等故障可被追踪和通知。对 Ubuntu 个人服务器、中小站点和 WordPress 环境,

weixin_34342905的博客 464

一个月跑了 5 次的“月度对账”:Cron 表达式的 7 个坑与 3 分钟自检法

它是给机器读的匹配规则,而我们在用人脑做语义还原,且没有任何验证环节。补上这个验证环节,成本极低:✅ 上线前让工具列出接下来 5 次执行时间(网页 / croniter / 框架解析器)✅ 日和周不要同时限定,除非你确认了当前实现是“或”还是“且”✅ 命令里的一律转义,或者干脆挪进脚本✅ 跨系统搬表达式,重查字段数、星期编号、L/W/#✅ 容器里显式设时区,别赌默认值✅ 用 flock 防重叠,用日志和告警让失败可见写死 29/30/31 号的表达式是定时炸弹。

2601_96611753的博客 211

Ubuntu 18.04 cron 实战:从环境变量到日志追踪的可靠定时任务配置

Cron 是 Linux 系统中最基础、最稳定的任务调度机制,其核心原理基于守护进程轮询 crontab 文件并按时间表达式触发命令执行。它不依赖用户登录或图形界面,具备高确定性与低运维侵入性,技术价值在于为基础设施级自动化提供‘开箱即用’的可靠性保障。典型应用场景包括日志轮转、数据库备份、监控采集等系统维护任务。然而在 Ubuntu 18.04 环境中,因 Vixie-cron 实现限制、PATH 环境变量缺失、权限模型严格及日志静默丢弃等问题,极易导致任务静默失败。本文聚焦 Ubuntu 18.04 平

weixin_30664615的博客 338

CentOS 8 中使用 Cron 实现生产级定时任务自动化

Cron 是 Linux 系统中最基础、最稳定的周期性任务调度机制,其核心原理是通过守护进程 crond 解析 crontab 文件中的时间表达式,在匹配时刻派生子进程执行指定命令。相比 systemd timer 或应用层调度(如 @Scheduled),Cron 具备零依赖、环境变量继承可靠、日志格式统一、调试门槛低等工程优势,特别适合日志轮转、备份清理、证书续签等独立运维任务。在 CentOS 8 这一以 RHEL 8 为基底、默认启用 systemd 但保留 cronie 的企业发行版中,Cron

weixin_34355559的博客 317
上一篇: Java Elasticsearch 使用
下一篇: Mybatis 二级缓存简单示例
_萧_
博客等级 码龄10年 55粉丝 157原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值