我正在尝试在hangfire中创建定期作业,每月第二个星期一运行一次,如下所示:
1. Monday, May 14, 2018 8:00 AM
2. Monday, June 11, 2018 8:0 AM
3. Monday, July 9, 2018 8:00 AM
4. Monday, August 13, 2018 8:00 AM
5. Monday, September 10, 2018 8:00 AM
我在 stackoverflow 中找到了 this 答案,但由于这不是用于调度hangifre作业的标准 cron,我无法使用它。
我的问题是我可以使用以下格式制作这样的表达式吗
* * * * * (min hour day/month month day/week)
以下命令似乎对我有用。
0 8 ? * MON#2
假设您希望此作业在每月第二个星期一上午 8 点执行,# 字符允许您指定任何给定月份的“第 n”天。我们使用?日/月行中的字符,因为只要是第二个星期一,我们就可以接受任何数字日。
在此处了解有关特殊字符的更多信息:http://www.quartz-scheduler.org/documentation/quartz-2.2.2/tutorials/crontrigger.html#special-characters
以下是每个第二个星期一三个不同时间的 cron,查看模式并根据您需要的日期及时更改
对于每月第二个星期一的 00:00,请尝试以下操作: 0 0 0 ? 1 月 1 日星期一#2 *
每月第二个星期一的 10:30,请尝试以下操作: 0 30 10 ? 1 月 1 日星期一#2 *
每月第二个星期一的 13:30,请尝试以下操作: 0 30 13 ? 1 月 1 日星期一#2 *
使用其他答案中建议的
Mon#2
之类的星期几是非标准,并且未由ISC Cron(大多数系统使用的Vixie Cron衍生品,包括大多数Linux发行版和BSD)实现。它肯定不在 Debian 最新的 cron 3.0pl1-186+b1 测试包的 crontab(5) 页面中。
与此问题更相关,该问题询问 C# 的 Hangfire,Performing Recurrent Tasks 文档含糊不清,仅指出“您还可以使用 CRON 表达式 来指定更复杂的计划”,依赖于维基百科链接提供更多详细信息。进一步挖掘,HangfireIO Cronos 项目(我认为它是底层 cron 实现)实际上确实注意到它支持非标准
L
、W
和 #
字符。
这意味着 Hangfire 用户确实可以使用
0 8 * * Mon#2
在每个月的第二个星期一早上 8 点运行。 (这里的其他答案使用问号,但 HangfireIO 的文档说这在其实现中与 *
同义,所以我认为没有理由添加另一个非标准字符。)
这是一个没有非标准字符的解决方案,应该可以在 BSD 和 Linux 等 Posix 风格的系统上工作:
#m h dom mo dow command
0 8 * * Mon d=$(date +\%e) && [ $d -ge 8 ] && [ $d -le 14 ] && echo "2nd Monday"
由于 cron 无法自行处理此问题,因此我们调用
date
来获取该月的日期,然后确保它是 8 号到 14 号。我们也可以将其实现为 0 8 8-14 * * [ $(date +\%w) = 1 ] && echo "2nd Monday"
,但是该 cron 作业每月运行(并且不执行任何操作)六次(每年 72 次),而该 cron 作业每月运行(并且不执行任何操作)3-4 次(40 次)一年),从而减少对系统日志的污染。
由于 Hangfire 是 C# 且可能无法在 Posix 风格的系统上运行,因此您不应依赖 Bash/Posix shell 逻辑或 Posix
date
命令。这个答案是为了完整性,因为 #
不是标准的。
请注意,
0 8 8-14 * Mon
不起作用,因为 cron 将一个月中的几天和一周中的几天视为并集而不是交集;该命令将在每月 8 日至 14 日或任何星期一运行。
给你。
0 0 12 ? 1/1 MON#2 *
minute hour day month dayofweek command
0 0 8-14 * 2 /path/here
这将在每月的第二个星期二午夜运行一项作业。
8-14 将星期二的出现限制为该月的第二周。
1-7 first week
8-14 second week
15-21 third week
22-28 forth week
29-31 fifth week