随着目前企业的业务越来越深入,很多业务场景会用到调度任务,例如:某公司需要每天在凌晨的1点生成昨日的数据生产报表,实现的方式有很多,目前运用到最多的则是调度任务,通俗讲就是定时任务,只需要设定好时间,到达该时间点就会自动执行任务,那么这种方式实现的具体原理是怎么样的呢,下面我会分几个层面给大家讲下实现的过程,当然也会把我最近使用的比较好的方式代码贴出来,供大家参考,若大家有更好的方式,也可以下方讨论(^_^)
定时任务的设定,需要用到Cron表达式,他可以灵活的配置任务的执行时间,具体配置规则大家可以去参考官方Cron的使用规则,也可以尝试在线配置,地址:https://qqe2.com/cron
这个是整合后的帮助类,里面涵盖了每日 每周 每月等相关定时任务的生成,同时会把执行的时间以集合的形式输出出来。下面我把需要用到的Cron帮助类代码贴出来,供大家参考:
using Newtonsoft.Json.Linq;
using NPOI.SS.Util;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CronHelper
{
public 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 CronHelper
{
/// <summary>
/// Cron表达式转换(默认开始时间为当前)
/// </summary>
/// <param name="cron">表达式</param>
/// <returns>最近5次要执行的时间</returns>
public 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>
public 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>
/// <param name="now">开始时间</param>
/// <returns>判断开始时间和结束时间截止需要执行的时间</returns>
public static List<DateTime> CronToDateTime(string cron, DateTime now, DateTime endTime)
{
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 (now > endTime)
{
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>
/// 返回周计划中间隔周所有的时间集合
/// </summary>
/// <param name="cron"></param>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <param name="weekNum"></param>
/// <returns></returns>
public static List<DateTime> CheckWeekIsExcute(string cron, DateTime startTime, DateTime endTime, int weekNum)
{
string[] cronArr = cron.Split(' ');
List<DateTime> returnList = new List<DateTime>();
// List<DateTime> newDateList = CronHelper.CronToDateTime(cron, startTime, endTime);
string[] weekDayArr = cronArr[5].Split(',');
foreach (string item in weekDayArr)
{
//间隔周期
int jgIndex = 0;
for (int k = startTime.Month; k <= endTime.Month; k++)
{
//判断默认从开始月份的第一天 获取本月多少天
int allDay = Convert.ToDateTime(startTime.Year + "-" + k + "-01").AddMonths(1).AddDays(-1).Day;
for (int i = 1; i < allDay; i++)
{
//获取默认是几月
string Monthindex = k.ToString().PadLeft(2, '0');
// 获取当前是周几
int dayOfweek = (int)Convert.ToDateTime(startTime.ToString("yyyy-" + Monthindex + "-") + i.ToString().PadLeft(2, '0')).DayOfWeek;
// 获取当前日期
DateTime nowDate = Convert.ToDateTime(startTime.ToString("yyyy-" + Monthindex + "-") + i.ToString().PadLeft(2, '0'));
if (nowDate < startTime.Date)
{
continue;
}
if (nowDate > endTime.Date)
{
break;
}
//表示该日期就可以执行 如果表达式的 周几等于当前周几 或者 表达式的周是周日并且 现在周是0 ’
//获取当前周默认是从周日开始 0-6
if (item == dayOfweek.ToString() || (item == "7" && dayOfweek == 0))
{
if (jgIndex == 0 || jgIndex % weekNum == 0)
{
returnList.Add(nowDate);
}
jgIndex++;
}
}
}
}
//.OrderBy(x => x.Date) .Where(x => x.Date >= startTime.Date).ToList()
return returnList;
}
/// <summary>
/// 返回周计划中间隔周所有的时间集合【跨年】
/// </summary>
/// <param name="cron"></param>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <param name="weekNum"></param>
/// <returns></returns>
public static List<DateTime> CheckWeekIsExcuteNew(string cron, DateTime startTime, DateTime endTime, int weekNum)
{
int weeknum = weekNum;
string[] cronArr = cron.Split(' ');
//存储原来的开始时间
DateTime oldstartTime = startTime;
string[] weekDayArr = cronArr[5].Split(',');
List<DateTime> resList = new List<DateTime>();
int jgIndex = 0;
DateTime startExcuteDate = new DateTime(1899, 01, 01);
foreach (var item in weekDayArr)
{
//重新获取星期几初始化开始日期为传入的日期
startTime = oldstartTime;
while (true)
{
//获取开始时间的月份有多少天
int monthDay = Convert.ToDateTime(startTime.ToString("yyyy-MM-01")).AddMonths(1).AddDays(-1).Day;
for (int i = startTime.Day; i <= monthDay; i++)
{
//判断间隔索引如果大于0则不需要执行循环函数计算执行的开始日期
if (jgIndex > 0)
{
break;
}
//获取当前日期
DateTime nowdate = Convert.ToDateTime(startTime.ToString("yyyy-MM-" + i.ToString().PadLeft(2, '0')));
//获取当前日期是周几 第一天是从周日开始执行的
int week = (int)(nowdate.DayOfWeek);
//判断当前周几和传入的周几比较
if (item == week.ToString() || (item == "7" && week == 0))
{
jgIndex++;
startExcuteDate = nowdate;
resList.Add(startExcuteDate);
break;
}
else if (i == monthDay)//判断是本月的最后一天则还未匹配到需要执行的日期则加一天
{
startTime = startTime.AddDays(1);
}
}
if (jgIndex > 0)
{
//获取到下次需要执行的日期
DateTime nextdate = startExcuteDate.AddDays(jgIndex * weeknum * 7);
//判断执行的日期大于结束日期则终止
if (nextdate > endTime)
{
jgIndex = 0;
startExcuteDate = new DateTime(1899, 01, 01);
break;
}
resList.Add(nextdate);
jgIndex++;
}
}
}
return resList;
}
/// <summary>
/// 根据制定的计划转换成cron表达式,张鑫
/// </summary>
/// <param name="dateJson"></param>
/// <returns></returns>
public static string ConvertToCron(CronModel dateJson)
{
string cron = string.Empty;
string excuteType = dateJson.excuteType;
if (excuteType.IsNotNullOrEmpty())
{
DateTime stDate = Convert.ToDateTime(dateJson.startTime);
//结束日期为空
if (dateJson.endTime.IsNullOrEmpty())
{
dateJson.endTime = "1899-01-01 00:00:00";
}
DateTime enDate = Convert.ToDateTime(dateJson.endTime);
int excuteTimes = Convert.ToInt32(dateJson.excuteTimes);
string excuteMonth = dateJson.excuteMonth;
string excuteMonth_Day = dateJson.excuteMonth_Day;
int excuteWeek = Convert.ToInt32(dateJson.excuteWeek);
string excuteWeek_Day = dateJson.excuteWeek_Day;
switch (excuteType)
{
case "Day":
cron = ConvertToCron(stDate, enDate, excuteTimes);
break;
case "Month":
cron = ConvertToCron(stDate, enDate, excuteMonth, excuteMonth_Day);
break;
case "Week":
cron = ConvertToCron(stDate, enDate, excuteWeek, excuteWeek_Day);
break;
default:
cron = $"0 0 0 {stDate.Day} {stDate.Month} ? {stDate.Year}";
break;
}
}
return cron;
}
/// <summary>
/// 转换为cron表达式日
/// </summary>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <param name=""></param>
/// <returns></returns>
public static string ConvertToCron(DateTime startTime, DateTime endTime, int excuteTimes)
{
Console.WriteLine("调用日生成表达式开始");
string yearCron = "*";
if (endTime.Year != 1899)
{
yearCron = $"{startTime.Year}-{endTime.Year}";
}
string cron = $"{startTime.Second} {startTime.Minute} {startTime.Hour} {startTime.Day}/{excuteTimes} * ? {yearCron}";
Console.WriteLine("调用日生成表达式结束");
return cron;
}
/// <summary>
/// 转换为cron表达式月
/// </summary>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <param name=""></param>
/// <returns></returns>
public static string ConvertToCron(DateTime startTime, DateTime endTime, string excuteMonth, string excuteMonth_Day)
{
Console.WriteLine("调用月生成表达式开始");
string yearCron = "*";
if (endTime.Year != 1899)
{
yearCron = $"{startTime.Year}-{endTime.Year}";
}
string cron = string.Empty;
string monthNum = GetMonthByChinese(excuteMonth);
if (monthNum.Contains("A"))
{
cron = $"{startTime.Second} {startTime.Minute} {startTime.Hour} {excuteMonth_Day} * ? {yearCron}";
}
else
{
cron = $"{startTime.Second} {startTime.Minute} {startTime.Hour} {excuteMonth_Day} {monthNum} ? {yearCron}";
}
Console.WriteLine("调用月生成表达式结束");
return cron;
}
/// <summary>
/// 转换为cron表达式周
/// </summary>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <param name=""></param>
/// <returns></returns>
public static string ConvertToCron(DateTime startTime, DateTime endTime, int excuteWeek, string excuteWeek_Day)
{
Console.WriteLine("调用周生成表达式开始");
string yearCron = "*";
if (endTime.Year != 1899)
{
yearCron = $"{startTime.Year}-{endTime.Year}";
}
string weekNum = GetWeekByChinese(excuteWeek_Day);
string cron = $"{startTime.Second} {startTime.Minute} {startTime.Hour} ? * {weekNum} {yearCron}";
Console.WriteLine("调用周生成表达式结束");
return cron;
}
/// <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++)
{
string num = str.Split(',')[i];
//if (num == "0")
//{
// num = "1";
//}
c.Weeks[int.Parse(num) - 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;
}
}
/// <summary>
/// 中文月份转化为数字
/// </summary>
/// <param name="chineseMonth"></param>
/// <returns></returns>
public static string GetMonthByChinese(string chineseMonth)
{
string[] monthArr = chineseMonth.Split(',');
string monthNum = string.Empty;
foreach (var item in monthArr)
{
switch (item)
{
case "一月": monthNum = monthNum + "," + 1; break;
case "二月": monthNum = monthNum + "," + 2; break;
case "三月": monthNum = monthNum + "," + 3; break;
case "四月": monthNum = monthNum + "," + 4; break;
case "五月": monthNum = monthNum + "," + 5; break;
case "六月": monthNum = monthNum + "," + 6; break;
case "七月": monthNum = monthNum + "," + 7; break;
case "八月": monthNum = monthNum + "," + 8; break;
case "九月": monthNum = monthNum + "," + 9; break;
case "十月": monthNum = monthNum + "," + 10; break;
case "十一月": monthNum = monthNum + "," + 11; break;
case "十二月": monthNum = monthNum + "," + 12; break;
default: monthNum = "A"; break;
}
}
return monthNum.Trim(',');
}
public static string GetWeekByChinese(string chineseWeek)
{
string[] weekArr = chineseWeek.Split(',');
string weekNum = string.Empty;
foreach (var item in weekArr)
{
switch (item)
{
case "星期一": weekNum = weekNum + "," + 1; break;
case "星期二": weekNum = weekNum + "," + 2; break;
case "星期三": weekNum = weekNum + "," + 3; break;
case "星期四": weekNum = weekNum + "," + 4; break;
case "星期五": weekNum = weekNum + "," + 5; break;
case "星期六": weekNum = weekNum + "," + 6; break;
case "星期日": weekNum = weekNum + "," + 7; break;
}
}
return weekNum.Trim(',');
}
#endregion
/// <summary>
/// 是否执行一次
/// </summary>
/// <param name="cron"></param>
/// <returns></returns>
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>
public 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;
}
}
}