1. 程式人生 > >quartz cron 表示式用法(CronTrigger 教程)

quartz cron 表示式用法(CronTrigger 教程)

介紹

cron 是一個 UNIX 工具,它已經存在了很長的時間,時間證明了它的排程能力很強大。CronTrigger class 是基於 cron 的排程功能。

CronTrigger 使用了 “cron 表示式”,可以建立一個 cron 表示式來觸發排程任務,例如:“每個星期一到星期五的上午 8 點”或者是“每個月的最後一個星期五的下午 1:30”。

cron 表示式非常強大,但有時候很難理解。本教程的目的就是解開建立 cron 表示式的謎題,給大家一個資源可查,省得去論壇或郵件列表中問其他人。

格式

cron 表示式是由 6 或 7 位由空格分開的欄位組成的。各個欄位可以包含任何被允許的值,伴隨著對應某個欄位所允許的特殊字元的各種組合。各個欄位如下:

欄位名稱 強制出現 允許的值 允許的特殊字元
0-59 ,-*/
0-59 ,-*/
0-23 ,-*/
日期 1-31 ,-*?/LW
1-12或者是 JAN-DEC ,-*/
星期 1-7或者是 SUN-SAT ,-*?/L#
空或者是1970-2099 ,-*/

很簡單的 cron 表示式:* * * * ? *
很複雜的,例如:0/5 14,18,3-39,52 * ? JAN,MAR,SEP MON-FRI 2002-2010

特殊字元

  • *(“所有的值”)-匹配某個欄位內的所有的值。例如,在“分”欄位中的“*”代表“每一分鐘”。

  • ?(“沒有特定的值”)-“?”只能用在“日期”和“星期”欄位中,在其他欄位中是不能用的。例如,我想要觸發器在某個月的某一天(比如是 10 號)觸發,但我不關注那天是星期幾,我就可以把 “10” 放到“日期”欄位中,把“?”放到“星期”欄位中。結合下面的例子來清楚的說明 cron 表示式的使用方法。

  • - -用來定義範圍。例如,在時欄位中的“10-12”意思是“10 點, 11 點和 12 點”。

  • ,-用來定義追加的值(列表)。例如,在星期欄位中的“MON,WED,FRI”意思是“星期一,星期三,星期五”。

  • /-用來定義增量。例如,在秒欄位中的“0/15”表示從0秒開始每隔15秒,就是“0 秒,15 秒,30 秒,45 秒,0 秒,15 秒……”。在分欄位中的“5/15”表示從 5 分開始每隔 15 分,就是“5分,20分,35分,50分,5 分, 20分……”。也可以在”空字元之後定義/,例如/5等價於在/前面有個0,即/5 等價於 0/5 。在日期欄位中的“1/3”的意思是“在某月的第 1 天開始每隔 3 天觸發一次”。

  • L(“last”)-只允許在兩個欄位中出現 “L” ,但 “L” 在這兩個欄位中每處的含義卻各不相同。例如,在日期欄位中的 “L” 意思是月末,即一個月的最後一天- 1 月的 31,平年 2 月的 28。如果 “L” 出現在星期欄位中,則表示 “7” 或 “SAT”,即星期六(在西方星期六是一週的最後一天)。但是在星期欄位中的 “L” 出現在一個數字之後意思是“某個月的最後一個星期幾”-例如“6L”意思是“某個月的最後一個星期五”。在使用“L”選項的時候最好不要再用列表、範圍值,否則的話會得到令人迷惑的結果。

  • W(“weekday 工作日”)-用來定義距離給定某一天最近的一個工作日(星期一到星期五)。例如,在日期欄位中定義了 “15W” 意思是“某個月中距離 15 號最近的一個工作日”。
    如果 15 號是星期六的話,觸發器會在星期五即 14 號觸發。如果 15 號是週日,觸發器會在下週一即 16 號觸發。如果 15 號是星期二的話,觸發器會在星期二當天 15 號觸發。然而,如果在日期欄位中定義了
    “1W”,如果 1 號是星期六的話,觸發器會在下個星期一即 3 號觸發,它不會跳回到上個月去觸發。“W” 只能定義在日期中欄位中,並且在日期欄位中只能定義單獨的一天,不能定義一個範圍或一個日期列表。

    “L” 和 “W” 還可以組合出現在日期欄位中,即“LW”,表示“某個月的最後一個工作日”。

  • #-用來定義“某個月的第 n 個星期幾”,# 只允許出現在星期欄位中。例如,在星期欄位中的“6#3”表示“某個月的第 3 個星期 5”(6 表示星期 5 ,3 表示某個月的第 3 周)。另一個例子:“2#1”意思是“某個月的第一個周的星期一 ”。
    “4#5”意思是“某個月中第 5 周的星期三 ”。注意,# 後面只允許出現 1-5(一般來說一個月中最多隻有 5 周,不知道有沒有可能有 6 周)。如果定義“#5”,在某個月中的第五週沒有五個工作日中的任何一天,那麼觸發器在當月就不會觸發。補充:我在我本地試了下,在星期欄位中定義
    “#5” 會報錯,# 之前必須要有數字,不知道是因為我的版本低還是我誤解了原文的意思,或者是原文中的“#5”意思是“1#5”、“2#5”、“3#5”、“4#5”、“5#5”、“6#5”、“7#5”中的一種,原文偷懶了下。

    月份和星期的英文單詞是不區分大小寫的。MON 和 mon 的含義是一樣的,都表示是星期一 。

例子

下面是一些完整的例子:

表示式 含義
0 0 12 * * ? 每天中午 12:00整觸發
0 15 10 ? * * 每個月的星期一到星期七的上午 10:15 分觸發,其實就是每天的上午 10:15,它和 0 15 10 * * ? 是等價的
0 15 10 * * ? 每天上午 10:15 分觸發
0 15 10 * * ? * 每天上午 10:15 分觸發
0 15 10 * * ? 2005 2015 年的每天上午 10:15 分觸發
0 * 14 * * ? 每天下午 2 點開始每隔 1 分鐘觸發一次,一直到下午 2:59 分之後結束。
0 0/5 14 * * ? 每天下午 2 點開始每隔 5 分鐘觸發一次,一直到下午 2:55 分之後結束。
0 0/5 14,18 * * ? 每天下午 2 點開始每隔 5 分鐘觸發一次,一直到下午 2:55 分之後結束。然後,每天下午 6 點開始每隔 5 分鐘觸發一次,一直到下午 6:55 分之後結束。
0 0-5 14 * * ? 每天下午 2 點開始每隔 1 分鐘觸發一次,一直到下午 2:05 分之後結束。
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 分觸發一次。
0 15 10 ? * 6L 每月的最後一個星期五的上午 10:15 分觸發一次。
0 15 10 ? * 6L 2002-2005 2002-2005 年的每月的最後一個星期五的上午 10:15 分觸發一次。
0 15 10 ? * 6#3 每月的第 3 周的星期五的上午 10:15 分觸發一次。
0 11 11 11 11 ? 每年的 11 月 11 日上午 11:11 分觸發一次。

注意日期和星期欄位中的“*”和“?”的作用。
補充:日期和星期欄位中不能同時出現 “?”,為什麼呢?一個定時器最終必須落實到某一天的某時某分某秒,其中日期和星期都可以表示某一天,但其他欄位卻不能表示某一天,所以這兩個欄位必須指定一個欄位,兩個欄位中都是“?”則無法指定是哪一天,所以語法上是不正確的。

注意

  • 暫時還不支援同時定義日期欄位和星期欄位(換句話說,日期欄位和星期欄位中必須有一者為“?”,但不能同時為“?”)。
  • 在晚上 12:00 到 1:00 之間設定觸發時間應該注意-“夏令時”會引起跳過或重複觸發,具體是跳過觸發還是觸發取決於時間是往快撥還是往慢撥。