寻求可被Cronos NuGet包解析的双周Cron表达式(每两周周一)
解决Cronos解析双周(每两周周一)Cron表达式的问题
你之前使用的0 0 * * 1/2表达式无效,原因是星期字段的1/2表示从周一开始,每隔2天触发,所以会匹配周一、周三、周五等日期,完全不符合双周需求。
正确实现方式
标准Cron语法没有原生的“双周”支持,结合Cronos包,推荐两种可靠方案:
方案1:基于14天间隔的表达式(仅适用于起始触发日为周一的场景)
使用以下表达式:
0 0 */14 * 1
- 含义:每天0点0分,每14天,且当天是周一的时候触发。
- 注意:如果起始日期的下一个周一之后的第14天恰好是周一,会连续触发;若遇到跨月或闰年导致14天后不是周一,会自动跳过,直到下一个符合条件的周一。
方案2:基于ISO周数过滤的可靠实现(推荐)
使用基础的周一触发表达式,再通过代码过滤ISO周数的奇偶性,确保每两周执行一次:
Cron表达式:
0 0 * * 1
修改后的测试代码:
DateTime startDate = new DateTime(2023, 8, 1, 0, 0, 0, DateTimeKind.Utc); var cron = CronExpression.Parse("0 0 * * 1"); // 获取起始基准周的ISO周数(取第一个触发的周一的周数) DateTime firstMonday = cron.GetNextOccurrence(startDate).Value; int startWeek = ISOWeek.GetWeekOfYear(firstMonday); bool targetWeekParity = startWeek % 2 == 0; // 标记基准周的奇偶性 // 获取第一个符合条件的触发时间 DateTime? nextOccurrence = cron.GetNextOccurrence(startDate); while (nextOccurrence != null) { int currentWeek = ISOWeek.GetWeekOfYear(nextOccurrence.Value); if (currentWeek % 2 == targetWeekParity) { break; } nextOccurrence = cron.GetNextOccurrence(nextOccurrence.Value); } // 获取后续触发时间 DateTime? nextOccurrence2 = cron.GetNextOccurrence(nextOccurrence.Value.AddDays(1)); while (nextOccurrence2 != null) { int currentWeek = ISOWeek.GetWeekOfYear(nextOccurrence2.Value); if (currentWeek % 2 == targetWeekParity) { break; } nextOccurrence2 = cron.GetNextOccurrence(nextOccurrence2.Value); } // 示例输出 // nextOccurrence.Value.ToString() → "8/2/2023 12:00:00 AM" // nextOccurrence2.Value.ToString() → "8/16/2023 12:00:00 AM"
- 原理:通过ISO周数的奇偶性判断,确保每两周的周一触发,不受月份天数、跨年度等因素影响,是最可靠的方式。
内容的提问来源于stack exchange,提问作者MG7
相关产品推荐
相关产品推荐

