Cron表达式定义及详情

请参考https://blog.csdn.net/HybridTheory_/article/details/88382442

使用C#解析Cron表达式,得到执行时间

class Cron
{private int[] seconds = new int[60];private int[] minutes = new int[60];private int[] hours = new int[24];private int[] days = new int[31];private int[] month = new int[12];private int[] weeks = new int[7];//2019-2099年private int[] year = new int[80];public int[] Seconds { get => seconds; set => seconds = value; }public int[] Minutes { get => minutes; set => minutes = value; }public int[] Hours { get => hours; set => hours = value; }public int[] Days { get => days; set => days = value; }public int[] Month { get => month; set => month = value; }public int[] Weeks { get => weeks; set => weeks = value; }public int[] Year { get => year; set => year = value; }public Cron(){for (int i = 0; i < 60; i++){seconds[i] = 0;minutes[i] = 0;}for (int i = 0; i < 24; i++){hours[i] = 0;}for (int i = 0; i < 31; i++){days[i] = 0;}for (int i = 0; i < 12; i++){month[i] = 0;}for (int i = 0; i < 7; i++){weeks[i] = 0;}for (int i = 0; i < 80; i++){year[i] = 0;}}public void Init(){for (int i = 0; i < 7; i++){weeks[i] = 0;}for (int i = 0; i < 31; i++){days[i] = 0;}}
}
/// <summary>
/// 在week上使用  5L表示本月最后一个星期五
///               7L表示本月最后一个星期天
///
/// 在week上使用  7#3表示每月的第三个星期天
///               2#4表示每月的第四个星期二
/// </summary>
public class CronHelp
{/// <summary>/// Cron表达式转换(默认开始时间为当前)/// </summary>/// <param name="cron">表达式</param>/// <returns>最近5次要执行的时间</returns>private static List<DateTime> CronToDateTime(string cron){try{List<DateTime> lits = new List<DateTime>();Cron c = new Cron();string[] arr = cron.Split(' ');Seconds(c, arr[0]);Minutes(c, arr[1]);Hours(c, arr[2]);Month(c, arr[4]);if (arr.Length < 7){Year(c, null);}else{Year(c, arr[6]);}DateTime now = DateTime.Now;int addtime = 1;while (true){if (c.Seconds[now.Second] == 1 && c.Minutes[now.Minute] == 1 && c.Hours[now.Hour] == 1 && c.Month[now.Month - 1] == 1 && c.Year[now.Year - 2019] == 1){if (arr[3] != "?"){Days(c, arr[3], DateTime.DaysInMonth(now.Year, now.Month), now);int DayOfWeek = (((int)now.DayOfWeek) + 6) % 7;if (c.Days[now.Day - 1] == 1 && c.Weeks[DayOfWeek] == 1){lits.Add(now);}}else{Weeks(c, arr[5], DateTime.DaysInMonth(now.Year, now.Month), now);int DayOfWeek = (((int)now.DayOfWeek) + 6) % 7;if (c.Days[now.Day - 1] == 1 && c.Weeks[DayOfWeek] == 1){lits.Add(now);}}}if (lits.Count >= 5){break;}c.Init();if (!arr[1].Contains('-') && !arr[1].Contains(',') && !arr[1].Contains('*') && !arr[1].Contains('/')){if (now.Minute == int.Parse(arr[1])){addtime = 3600;}}else if (arr[0] == "0" && now.Second == 0){addtime = 60;}now = now.AddSeconds(addtime);}return lits;}catch{return null;}}/// <summary>/// Cron表达式转换(自定义开始时间)/// </summary>/// <param name="cron">表达式</param>/// <param name="now">开始时间</param>/// <returns>最近5次要执行的时间</returns>private static List<DateTime> CronToDateTime(string cron, DateTime now){try{List<DateTime> lits = new List<DateTime>();Cron c = new Cron();string[] arr = cron.Split(' ');Seconds(c, arr[0]);Minutes(c, arr[1]);Hours(c, arr[2]);Month(c, arr[4]);if (arr.Length < 7){Year(c, null);}else{Year(c, arr[6]);}int addtime = 1;while (true){if (c.Seconds[now.Second] == 1 && c.Minutes[now.Minute] == 1 && c.Hours[now.Hour] == 1 && c.Month[now.Month - 1] == 1 && c.Year[now.Year - 2019] == 1){if (arr[3] != "?"){Days(c, arr[3], DateTime.DaysInMonth(now.Year, now.Month), now);int DayOfWeek = (((int)now.DayOfWeek) + 6) % 7;if (c.Days[now.Day - 1] == 1 && c.Weeks[DayOfWeek] == 1){lits.Add(now);}}else{Weeks(c, arr[5], DateTime.DaysInMonth(now.Year, now.Month), now);int DayOfWeek = (((int)now.DayOfWeek) + 6) % 7;if (c.Days[now.Day - 1] == 1 && c.Weeks[DayOfWeek] == 1){lits.Add(now);}}}if (lits.Count >= 5){break;}c.Init();if (!arr[1].Contains('-') && !arr[1].Contains(',') && !arr[1].Contains('*') && !arr[1].Contains('/')){if (now.Minute == int.Parse(arr[1])){addtime = 3600;}}else if (arr[0] == "0" && now.Second == 0){addtime = 60;}now = now.AddSeconds(addtime);}return lits;}catch{return null;}}/// <summary>/// Cron表达式转换(默认开始时间为当前)/// </summary>/// <param name="cron">表达式</param>/// <returns>最近要执行的时间字符串</returns>public static string GetNextDateTime(string cron){try{DateTime now = DateTime.Now;string[] arr = cron.Split(' ');if (IsOrNoOne(cron)){string date = arr[6] + "/" + arr[4] + "/" + arr[3] + " " + arr[2] + ":" + arr[1] + ":" + arr[0];if (DateTime.Compare(Convert.ToDateTime(date), now) >= 0){return date;}else{return null;}}Cron c = new Cron();Seconds(c, arr[0]);Minutes(c, arr[1]);Hours(c, arr[2]);Month(c, arr[4]);if (arr.Length < 7){Year(c, null);}else{Year(c, arr[6]);}int addtime = 1;while (true){if (c.Seconds[now.Second] == 1 && c.Minutes[now.Minute] == 1 && c.Hours[now.Hour] == 1 && c.Month[now.Month - 1] == 1 && c.Year[now.Year - 2019] == 1){if (arr[3] != "?"){Days(c, arr[3], DateTime.DaysInMonth(now.Year, now.Month), now);int DayOfWeek = (((int)now.DayOfWeek) + 6) % 7;if (c.Days[now.Day - 1] == 1 && c.Weeks[DayOfWeek] == 1){return now.ToString("yyyy/MM/dd HH:mm:ss");}}else{Weeks(c, arr[5], DateTime.DaysInMonth(now.Year, now.Month), now);int DayOfWeek = (((int)now.DayOfWeek) + 6) % 7;if (c.Days[now.Day - 1] == 1 && c.Weeks[DayOfWeek] == 1){return now.ToString("yyyy/MM/dd HH:mm:ss");}}}c.Init();if (!arr[1].Contains('-') && !arr[1].Contains(',') && !arr[1].Contains('*') && !arr[1].Contains('/')){if (now.Minute == int.Parse(arr[1])){addtime = 3600;}}else if (arr[0] == "0" && now.Second == 0){addtime = 60;}now = now.AddSeconds(addtime);}}catch{return null;}}/// <summary>/// Cron表达式转换(自定义开始时间)/// </summary>/// <param name="cron">表达式</param>/// <param name="now">开始时间</param>/// <returns>最近要执行的时间字符串</returns>public static string GetNextDateTime(string cron, DateTime now){try{string[] arr = cron.Split(' ');if (IsOrNoOne(cron)){string date = arr[6] + "/" + arr[4] + "/" + arr[3] + " " + arr[2] + ":" + arr[1] + ":" + arr[0];if(DateTime.Compare(Convert.ToDateTime(date),now)>0){return date;}else{return null;}}Cron c = new Cron();Seconds(c, arr[0]);Minutes(c, arr[1]);Hours(c, arr[2]);Month(c, arr[4]);if (arr.Length < 7){Year(c, null);}else{Year(c, arr[6]);}int addtime = 1;while (true){if (c.Seconds[now.Second] == 1 && c.Minutes[now.Minute] == 1 && c.Hours[now.Hour] == 1 && c.Month[now.Month - 1] == 1 && c.Year[now.Year - 2019] == 1){if (arr[3] != "?"){Days(c, arr[3], DateTime.DaysInMonth(now.Year, now.Month), now);int DayOfWeek = (((int)now.DayOfWeek) + 6) % 7;if (c.Days[now.Day - 1] == 1 && c.Weeks[DayOfWeek] == 1){return now.ToString("yyyy/MM/dd HH:mm:ss");}}else{Weeks(c, arr[5], DateTime.DaysInMonth(now.Year, now.Month), now);int DayOfWeek = (((int)now.DayOfWeek) + 6) % 7;if (c.Days[now.Day - 1] == 1 && c.Weeks[DayOfWeek] == 1){return now.ToString("yyyy/MM/dd HH:mm:ss");}}}c.Init();if (!arr[1].Contains('-') && !arr[1].Contains(',') && !arr[1].Contains('*') && !arr[1].Contains('/')){if (now.Minute == int.Parse(arr[1])){addtime = 3600;}}else if (arr[0] == "0" && now.Second == 0){addtime = 60;}now = now.AddSeconds(addtime);}}catch{return null;}}/// <summary>/// Cron表达式转换成中文描述/// </summary>/// <param name="cronExp"></param>/// <returns></returns>public static string TranslateToChinese(string cronExp){if (cronExp == null || cronExp.Length < 1){return "cron表达式为空";}string[] tmpCorns = cronExp.Split(" ");StringBuilder sBuffer = new StringBuilder();if (tmpCorns.Length == 6){//解析月if (!tmpCorns[4].Equals("*")){sBuffer.Append(tmpCorns[4]).Append("月");}else{sBuffer.Append("每月");}//解析周if (!tmpCorns[5].Equals("*") && !tmpCorns[5].Equals("?")){char[] tmpArray = tmpCorns[5].ToCharArray();foreach (char tmp in tmpArray){switch (tmp){case '1':sBuffer.Append("星期天");break;case '2':sBuffer.Append("星期一");break;case '3':sBuffer.Append("星期二");break;case '4':sBuffer.Append("星期三");break;case '5':sBuffer.Append("星期四");break;case '6':sBuffer.Append("星期五");break;case '7':sBuffer.Append("星期六");break;case '-':sBuffer.Append("至");break;default:sBuffer.Append(tmp);break;}}}//解析日if (!tmpCorns[3].Equals("?")){if (!tmpCorns[3].Equals("*")){sBuffer.Append(tmpCorns[3]).Append("日");}else{sBuffer.Append("每日");}}//解析时if (!tmpCorns[2].Equals("*")){sBuffer.Append(tmpCorns[2]).Append("时");}else{sBuffer.Append("每时");}//解析分if (!tmpCorns[1].Equals("*")){sBuffer.Append(tmpCorns[1]).Append("分");}else{sBuffer.Append("每分");}//解析秒if (!tmpCorns[0].Equals("*")){sBuffer.Append(tmpCorns[0]).Append("秒");}else{sBuffer.Append("每秒");}}return sBuffer.ToString();}#region 初始化Cron对象private static void Seconds(Cron c, string str){if (str == "*"){for (int i = 0; i < 60; i++){c.Seconds[i] = 1;}}else if (str.Contains('-')){int begin = int.Parse(str.Split('-')[0]);int end = int.Parse(str.Split('-')[1]);for (int i = begin; i <= end; i++){c.Seconds[i] = 1;}}else if (str.Contains('/')){int begin = int.Parse(str.Split('/')[0]);int interval = int.Parse(str.Split('/')[1]);while (true){c.Seconds[begin] = 1;if ((begin + interval) >= 60)break;begin += interval;}}else if (str.Contains(',')){for (int i = 0; i < str.Split(',').Length; i++){c.Seconds[int.Parse(str.Split(',')[i])] = 1;}}else{c.Seconds[int.Parse(str)] = 1;}}private static void Minutes(Cron c, string str){if (str == "*"){for (int i = 0; i < 60; i++){c.Minutes[i] = 1;}}else if (str.Contains('-')){int begin = int.Parse(str.Split('-')[0]);int end = int.Parse(str.Split('-')[1]);for (int i = begin; i <= end; i++){c.Minutes[i] = 1;}}else if (str.Contains('/')){int begin = int.Parse(str.Split('/')[0]);int interval = int.Parse(str.Split('/')[1]);while (true){c.Minutes[begin] = 1;if ((begin + interval) >= 60)break;begin += interval;}}else if (str.Contains(',')){for (int i = 0; i < str.Split(',').Length; i++){c.Minutes[int.Parse(str.Split(',')[i])] = 1;}}else{c.Minutes[int.Parse(str)] = 1;}}private static void Hours(Cron c, string str){if (str == "*"){for (int i = 0; i < 24; i++){c.Hours[i] = 1;}}else if (str.Contains('-')){int begin = int.Parse(str.Split('-')[0]);int end = int.Parse(str.Split('-')[1]);for (int i = begin; i <= end; i++){c.Hours[i] = 1;}}else if (str.Contains('/')){int begin = int.Parse(str.Split('/')[0]);int interval = int.Parse(str.Split('/')[1]);while (true){c.Hours[begin] = 1;if ((begin + interval) >= 24)break;begin += interval;}}else if (str.Contains(',')){for (int i = 0; i < str.Split(',').Length; i++){c.Hours[int.Parse(str.Split(',')[i])] = 1;}}else{c.Hours[int.Parse(str)] = 1;}}private static void Month(Cron c, string str){if (str == "*"){for (int i = 0; i < 12; i++){c.Month[i] = 1;}}else if (str.Contains('-')){int begin = int.Parse(str.Split('-')[0]);int end = int.Parse(str.Split('-')[1]);for (int i = begin; i <= end; i++){c.Month[i - 1] = 1;}}else if (str.Contains('/')){int begin = int.Parse(str.Split('/')[0]);int interval = int.Parse(str.Split('/')[1]);while (true){c.Month[begin - 1] = 1;if ((begin + interval) >= 12)break;begin += interval;}}else if (str.Contains(',')){for (int i = 0; i < str.Split(',').Length; i++){c.Month[int.Parse(str.Split(',')[i]) - 1] = 1;}}else{c.Month[int.Parse(str) - 1] = 1;}}private static void Year(Cron c, string str){if (str == null || str == "*"){for (int i = 0; i < 80; i++){c.Year[i] = 1;}}else if (str.Contains('-')){int begin = int.Parse(str.Split('-')[0]);int end = int.Parse(str.Split('-')[1]);for (int i = begin - 2019; i <= end - 2019; i++){c.Year[i] = 1;}}else{c.Year[int.Parse(str) - 2019] = 1;}}private static void Days(Cron c, string str, int len, DateTime now){for (int i = 0; i < 7; i++){c.Weeks[i] = 1;}if (str == "*" || str == "?"){for (int i = 0; i < len; i++){c.Days[i] = 1;}}else if (str.Contains('-')){int begin = int.Parse(str.Split('-')[0]);int end = int.Parse(str.Split('-')[1]);for (int i = begin; i <= end; i++){c.Days[i - 1] = 1;}}else if (str.Contains('/')){int begin = int.Parse(str.Split('/')[0]);int interval = int.Parse(str.Split('/')[1]);while (true){c.Days[begin - 1] = 1;if ((begin + interval) >= len)break;begin += interval;}}else if (str.Contains(',')){for (int i = 0; i < str.Split(',').Length; i++){c.Days[int.Parse(str.Split(',')[i]) - 1] = 1;}}else if (str.Contains('L')){int i = str.Replace("L", "") == "" ? 0 : int.Parse(str.Replace("L", ""));c.Days[len - 1 - i] = 1;}else if (str.Contains('W')){c.Days[len - 1] = 1;}else{c.Days[int.Parse(str) - 1] = 1;}}private static void Weeks(Cron c, string str, int len, DateTime now){if (str == "*" || str == "?"){for (int i = 0; i < 7; i++){c.Weeks[i] = 1;}}else if (str.Contains('-')){int begin = int.Parse(str.Split('-')[0]);int end = int.Parse(str.Split('-')[1]);for (int i = begin; i <= end; i++){c.Weeks[i - 1] = 1;}}else if (str.Contains(',')){for (int i = 0; i < str.Split(',').Length; i++){c.Weeks[int.Parse(str.Split(',')[i]) - 1] = 1;}}else if (str.Contains('L')){int i = str.Replace("L", "") == "" ? 0 : int.Parse(str.Replace("L", ""));if (i == 0){c.Weeks[6] = 1;}else{c.Weeks[i - 1] = 1;c.Days[GetLastWeek(i, now) - 1] = 1;return;}}else if (str.Contains('#')){int i = int.Parse(str.Split('#')[0]);int j = int.Parse(str.Split('#')[1]);c.Weeks[i - 1] = 1;c.Days[GetWeek(i - 1, j, now)] = 1;return;}else{c.Weeks[int.Parse(str) - 1] = 1;}//week中初始化day,则说明day没要求for (int i = 0; i < len; i++){c.Days[i] = 1;}}#endregion#region 方法public static bool IsOrNoOne(string cron){if (cron.Contains('-') || cron.Contains(',') || cron.Contains('/') || cron.Contains('*')){return false;}else{return true;}}/// <summary>/// 获取最后一个星期几的day/// </summary>/// <param name="i">星期几</param>/// <param name="now"></param>/// <returns></returns>private static int GetLastWeek(int i, DateTime now){DateTime d = now.AddDays(1 - now.Day).Date.AddMonths(1).AddSeconds(-1);int DayOfWeek = ((((int)d.DayOfWeek) + 6) % 7) + 1;int a = DayOfWeek >= i ? DayOfWeek - i : 7 + DayOfWeek - i;return DateTime.DaysInMonth(now.Year, now.Month) - a;}/// <summary>/// 获取当月第几个星期几的day/// </summary>/// <param name="i">星期几</param>/// <param name="j">第几周</param>/// <param name="now"></param>/// <returns></returns>public static int GetWeek(int i, int j, DateTime now){int day = 0;DateTime d = new DateTime(now.Year, now.Month, 1);int DayOfWeek = ((((int)d.DayOfWeek) + 6) % 7) + 1;if (i >= DayOfWeek){day = (7 - DayOfWeek + 1) + 7 * (j - 2) + i;}else{day = (7 - DayOfWeek + 1) + 7 * (j - 1) + i;}return day;}#endregion}

调用方法示例

string cron="0 15 10 * * ?";
CronHelp.GetNextDateTime(cron, DateTime.Now);
CronHelp.CronToDateTime(cron, DateTime.Now);
CronHelp.CronToDateTime(cron);

C#/.NET 解析Cron表达式,根据Cron表达式获取最近执行时间相关推荐

  1. java cron表达式 每天凌晨两点_Quartz cron表达式(时间表达式)

    Quartz cron表达式(时间表达式) 2017年03月28日 09:56:42 阅读数:3845 标签: quartz 更多 版权声明:本文为博主原创文章,未经博主允许不得转载. https:/ ...

  2. 根据cron表达式获取下次执行时间

    一.根据cron表达式获取下次执行时间 直接上代码 String cronExpress = "xxxxxxxxxx";//此处为cron表达式try{CronExpression ...

  3. Cron(七子表达式)表达式

    一.Cron表达式的格式: Quartzcron 表达式的格式十分类似于 UNIX cron 格式,但还是有少许明显的区别.区别之一就是 Quartz 的格式向下支持到秒级别的计划,而UNIX cro ...

  4. java 解析el表达式_Javaweb El表达式实例详解

    EL全称 Expression Language(表达式语言),是jsp2.0最重要的特性之一,可以利用EL表达式来访问应用程序中的数据,来消除jsp页面中的java脚本. el表达式的语法 expr ...

  5. access里面的表达式运用_Access表达式解析

    以下是一些表达式示例. 表达式 用途 =[ 订购日期 ]-[ 发货日期 ] 计算报表上两个文本框控件中的值之差 Date() 将表中字段的默认值设置为当前日期 总 价 : CCur([ 订 单 明 细 ...

  6. python之三元表达式嵌套三元表达式解析

    python的三元表达式相信学过python的朋友都会.但是大部分学python的朋友不知道的是三元表达式还可以嵌套三元表达式. 请看代码案例: cmp = lambda a, b: 0 if a = ...

  7. (二)Thymeleaf标准表达式之——简单表达式

    2. 标准表达式(Standard Expression Syntax) 标准表达式包含以下几个方面: 简单表达式: 变量表达式: ${...} 选择变量表达式: *{...} 消息表达式: #{.. ...

  8. 《专家系统(开发)--表达式检测--与表达式模板一起使用》

    2019独角兽企业重金招聘Python工程师标准>>> <专家系统破解篇 九.Simple Rule Engine规则推理引擎三(表达式分析)> 表达式模板化配置的思路 ...

  9. Java堆栈的应用2----------中缀表达式转为后缀表达式的计算Java实现

    1.堆栈-Stack 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除 ...

最新文章

  1. 推荐一个比较好的SQL工具——SQL Prompt
  2. C++11之异步调用
  3. 一个优秀的Push平台,需要经历怎样的前世今生
  4. php左侧,php左侧补零
  5. 使用.net core和abp框架实现动态webapi的简单说明
  6. PCB制图 | Altium Designer 20软件汉化
  7. Android等宽字体
  8. 『HarmonyOS』万物互联,分布式操作系统
  9. 【学生个人网页设计作品】使用HMTL制作一个超好看的保护海豚动物网页
  10. Racket GUI,使用message%显示图片
  11. 2021年中国宽带接入情况、用户规模及使用情况分析[图]
  12. 卸载office2010安装包时提示语言不受系统支持
  13. 实用!四个方法训练自己的设计思维
  14. 关于emacs字体放大问题
  15. 直通大厂web入门级网页快速开发(建议收藏)
  16. 凤翅医话——治腰椎间盘突出
  17. VNX中的DataMover
  18. PC怎么通过Console口连接并配置交换机
  19. 合并报表编制采用的理论_3.合并报表编制理论知识(必读)详解
  20. 衡阳高铁铁路学校计算机专业,衡阳2021年铁路学校都有哪些专业好

热门文章

  1. 翻译:Firefox for Pentester: Privacy and Protection Configurations
  2. C语言学习 查询水果价格
  3. 全球首个AI模型开发管理标准正式发布,九章云极DataCanvas公司助力AI工程化新发展
  4. 年薪50万的AI和年薪80万的区块链,哪一个更适合你?
  5. 12306网上购票进行身份核验的步骤
  6. 视频转接芯片方案IT6251FN:LVDS转EDP
  7. Windows 10 关闭人脉软件
  8. IDL 文本编码、代码补全快捷方式、IDL doc、格式器、行号显示设置
  9. Html5添加SVG生成图案花纹背景样式的js插件教程
  10. 【单片机】STM32 最小板 学习笔记