kdnakt blog

hello there.

Javaで利用できるCron式を集めてみた

cron-utilsというJavaのライブラリがあり、様々なスタイルでCron式を定義することができる。 Quarkusのschedulerエクステンションで利用されていたので、それぞれのスタイルの特徴をまとめてみた。

github.com

 

 

[Unixスタイル]

最もオーソドックスなunixの場合、書式は以下の通りで指定可能なフィールドは5つである。

分 時 日 月 曜日

ja.wikipedia.org

それぞれのフィールドには通常数字を設定するが、以下の特殊記号を利用することもできる。

  • コンマ(,):値のリストを指定(例:1,2,4)
  • ダッシュ(-):値の範囲を指定(例:1-3であれば、1,2,3と同じ意味)
  • アスタリスク(*):そのフィールドの取りうる値すべて(例:分のフィールドであれば、毎分の意味)
  • スラッシュ(/)*1:一定値ごとの間隔(例:分のフィールドで0/10であれば、0分から10分おき。0,10,20,30,40,50と同じ意味)

曜日のフィールドは日曜日が0で始まり土曜日が6で終わるが、7を指定しても日曜日として扱われる。

日付と曜日が同時に指定されている場合、どちらかを満たした時点でイベントが実行される。

@yearlyのように1月1日に毎年実行する、という特殊な表記法も存在する。

 

[cron4jスタイル]

cron4jの場合、書式は以下の通りで指定可能フィールドは5つである。

分 時 日 月 曜日

www.sauronsoftware.it

基本的な書式はunixと同じだが、パイプ(|)で複数のパターンを結合できるという特徴がある。

0 5 * * *|8 10 * * *|22 17 * * *

のように書くと、毎日5時0分、10時8分、17時22分にタスクが実行される。

また、日のフィールドでは特殊記号として「L」を利用すると「その月の最終日」という意味になる。

 

[quartsスタイル]

quartsの場合、書式は以下の通りで指定可能なフィールドは6つである。

秒と年を指定できるのが特徴的だ。

秒 分 時 日 月 曜日 年

www.quartz-scheduler.org

  

曜日にLをつけて「最終○曜日」を表すこともできる。「最終金曜」であれば「6L」のようにする。

また、「6#3」のように#を利用すると、「第3金曜」を表すことができる。

CronTrigger (Quartz Enterprise Job Scheduler 1.8.6 API)

 

日のフィールドでは特殊記号として「L」を利用すると「その月の最終日」という意味になる。

また、「W」を使うと同月内の直近の平日を指定することもできる。「15W」の場合、15日が土曜日なら14日金曜に発火、15日が火曜日ならば15日に発火する。

www.quartz-scheduler.org

 

[Springスタイル]

springの場合、書式は以下の通りで指定可能なフィールドは6つである。

こちらも秒を指定できる。

秒 分 時 日 月 曜日

docs.spring.io

Springの場合は、式を設定するときに、同時にタイムゾーンを指定することもできる。

@Scheduled(cron="*/5 * * * * *", zone="Asia/Tokyo")

  

[番外編:Amazon CloudWatch Event]

Javaとは直接関係はないが*2Amazon CloudWatch Eventでもcron式を利用することができる。

docs.aws.amazon.com

CloudWatch Eventsは以下の2通りの記述方法がある。

  • cron方式
  • rate方式

 

このうち、cron方式の場合、書式は以下の通り。

cron(分 時 日 月 曜日 年)

特徴としては、年(year)の指定が可能なところ。

また、これまで説明したような、L、W、#の特殊記号もそれぞれ利用できる。

 

[まとめ]

まとめると、以下のようになる。

  曜日 備考
unix × ×  
cron4j × ×
  • パイプで複数パターン連結可能
  • 日にLで月末
quarts
  • 年は省略可能
  • 曜日にLで「最終○曜」 、#で「第X○曜」
  • 日にLで月末、Wで同月の直近の平日
spring ×  
CloudWatch Events ×
  • cron()で式を囲む
  • L、W、#の特殊記号も利用可能

 

それぞれのスタイルで利用可能なフィールドの種類はもとより、/記号を利用したステップ実行すらちゃんと理解していなかったが、改めて調べてみると他にも特殊記号がいろいろあって勉強になった。

 

Cronイベントでも同じタイミングで集中させるとサーバーに負荷がかかってよくない、という内容が書かれていたAmazon Builder's Libraryの記事へリンクを貼って締める。

The Amazon Builder's Libraryを読む:『ジッターを伴うタイムアウト、再試行、およびバックオフ』 - kdnakt blog

aws.amazon.com

*1:実装によっては利用できない場合もある、らしい。

*2:AWS SDK for Javaを利用してcron式を設定することはできる。