2025年cron表达式使用详解及C中创建cron表达式,和计算下次执行时间

cron表达式使用详解及C中创建cron表达式,和计算下次执行时间第一部分 cron 基础 一 Cron 表达式是一个字符串 字符串以空格隔开 分为 5 或 6 个域 每一个域代表一个含义 系统支持的表达式格式如下 DayofWeek 为可选域 Seconds Minutes Hours DayofMonth Month DayofWeek

大家好,我是讯享网,很高兴认识大家。

 

第一部分:cron基础

一、Cron表达式是一个字符串,字符串以空格隔开,分为5或6个域,每一个域代表一个含义,系统支持的表达式格式如下(DayofWeek 为可选域。):

二、字段含义

Seconds: 可出现"* / , -"四个字符,有效范围为0-59的整数
Minutes: 可出现"* / , -"四个字符,有效范围为0-59的整数
Hours: 可出现"* / , -"四个字符,有效范围为0-23的整数
DayofMonth: 可出现"* / , - ?"五个字符,有效范围为0-31的整数
Month: 可出现", - * /"四个字符,有效范围为1-12的整数或JAN-DEC
DayofWeek: 可出现"* / , - ?"五个字符,有效范围为0-6的整数或SUN-SAT两个范围。0表示星期天,1表示星期一, 依次类推
1
2
3
4
5
6
* 表示匹配该域的任意值,假如在Minutes域使用*, 即表示每分钟都会触发事件。
? 字符仅被用于天(月)和天(星期)两个子表达式,表示不指定值,当2个子表达式其中之一被指定了值以后,为了避免冲突,需要将另一个子表达式的值设为“?”。
- 表示范围,例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次。
/ 表示起始时间开始触发,然后每隔固定时间触发一次,例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次。
, 表示列出枚举值值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。
1
2
3
4
5
三、一些例子:

0 0 10,14,16 * * ? 每天上午10点,下午2点,4点触发 

0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时触发  

0 0 12 ? * WED 表示每个星期三中午12点触发  

0 0 12 * * ? 每天中午12点触发 

0 15 10 ? * * 每天上午10:15触发 

0 15 10 * * ? 每天上午10:15触发 

0 15 10 * * ? * 每天上午10:15触发 

0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发 


讯享网

0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发 

0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 

0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发 

0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发 

0 15 10 ? * MON-FRI 周一至周五的上午10:15触发 

0 15 10 15 * ? 每月15日上午10:15触发 

0 15 10 L * ? 每月最后一日的上午10:15触发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
四、表达式生成器
对照上面的字段含义写自定义的cron时间表达式,写完后可以到 http://cron.e2.com/ 验证下。

上面基本已经够用了,如果还想了解下下面几个使用方法可参照https://blog.csdn.net/fanrenxiang/article/details/

L:表示last,例如星期中表示7或SAT,月份中表示最后一天31或30,6L表示这个月倒数第6天,FRIL表示这个月的最后一个星期五
W:只能用在月份中,表示最接近指定天的工作日
#:只能用在星期中,表示这个月的第几个周几,例如6#3表示这个月的第3个周五
 

来源:https://blog.csdn.net/longgeaisisi/article/details/

 

第二部分:C#中创建cron表达式

 public string CreateCronExpression(MainWindow info) { //算出cron表达式 分时部分 string baseCron = $"{info.StartTime.Minute} {info.StartTime.Hour} "; //算出cron表达式 日部分, baseCron = baseCron + (info.IntervalType == 2 ? "?" : info.StartTime.Day+"/"+info.Interval)+ " * "; //算出cron表达式 星期部分 baseCron = baseCron + (info.IntervalType == 2 ? TransferWeek2Num(info.IntervalStart) : "?"); return baseCron; } public string TransferWeek2Num(string weeks) { string[] weekArr = weeks.Split(","); StringBuilder numStr = new StringBuilder(); foreach(string item in weekArr ) { switch( item ) { case "周一": numStr.Append("2,"); break; case "周二": numStr.Append("3,"); break; case "周三": numStr.Append("4,"); break; case "周四": numStr.Append("5,"); break; case "周五": numStr.Append("6,"); break; case "周六": numStr.Append("7,"); break; case "周日": numStr.Append("1,"); break; default: break; } } return numStr.ToString().TrimEnd(','); }

讯享网

 

讯享网using System; using Castle.Core.Internal; using Quartz; using Satum.Data.MaintenancePlan.DTO; namespace Satum.MysmCommon.Utils { public class CronToDateTimeHelper { /// <summary> /// cron 表达式计算起始时间 /// </summary> /// <param name="cronStr"> 注意表达式是 5 域还是 6 域,5 域的需要 leftPad = true</param> /// <param name="duration"> 单位是分钟 </param> /// <param name="startTime"></param> /// <param name="leftPad"> 是否需要补齐 6 域 </param> /// <returns></returns> /// <exception cref="ArgumentException"></exception> public static DateTimeDto Transfer(string cronStr, int duration, DateTime startTime, bool leftPad = false) { if (cronStr.IsNullOrEmpty() || duration == 0) { throw new ArgumentException("Cron 表达式计算缺少必要参数"); } string[] corns = cronStr.Split(" "); if( corns.Length != 5 ) { throw new ArgumentException("Cron 表达式错误,只能包含 5 个域"); } // Quartz 中 天 和 周 不能同时为 ‘*’ if( corns[2] == corns[4] && corns[2] == "*" ) { corns[4] = "?"; cronStr = string.Join(" ", corns); } // 补齐 6 个域,PHP 能解析的表达式为 5 个域,数据库存储的是 5 个域 // Quartz 解析需要 6 个域 if (leftPad) { cronStr = "0 " + cronStr; } // 解析 cron 表达式 CronExpression cronExpr = new CronExpression(cronStr); DateTimeOffset? nextTime = cronExpr.GetNextValidTimeAfter(startTime.ToUniversalTime()); if (nextTime.HasValue == false) { throw new ArgumentException("Cron 表达式错误"); } DateTimeDto date = new DateTimeDto(); // 开始时间 // DateTimeOffset 是无时区 utc 时间,这里计算开始时间时需要转换成本地时间(东 8 区) date.BeginTime = nextTime.Value.DateTime.ToLocalTime(); // 结束时间 double seconds = (double)duration * 60; date.EndTime = date.BeginTime.AddSeconds(seconds); return date; } /// <summary> /// 检查Cron表达式是否符合格式 /// </summary> /// <param name="cronStr">注意表达式是 5 域还是 6 域,5 域的需要 leftPad = true</param> /// <param name="leftPad">是否需要补齐 6 域</param> /// <returns></returns> public static bool CheckCronExpressionFormat(string cronStr, bool leftPad = false) { if( cronStr.IsNullOrEmpty() ) { return false; } // 补齐 6 个域,PHP 能解析的表达式为 5 个域,数据库存储的是 5 个域 // Quartz 解析需要 6 个域 if( leftPad ) { cronStr = "0 " + cronStr; } //验证Cron表达式是否符合格式,抛出异常则表示不符合Cron表达式格式 try { var cronExpr = new CronExpression(cronStr); } catch(Exception) { return false; } return true; } } } 

 

小讯
上一篇 2025-01-14 19:07
下一篇 2025-01-10 16:54

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/47841.html