Apexバッチのスケジュール登録は週または月単位となっています。そのためバッチを一年後にスケジュール登録したい場合は別の方法を検討する必要があります。
Apexでは『System.schedule』をつかってスケジュールバッチの登録ができます。これは一年後の日付でも登録が可能です。
private void doNextBatchSchedule(String nextBatchName, Date targetDate) { ApexSampleScheduler cls = new ApexSampleScheduler(); String sch = '0 0 1 1 JAN ? ' + String.valueOf(targetDate.year()); System.schedule(nextBatchName, sch, cls); }
日時の登録は左から秒・分・時・日・月・曜日・年と指定できます。月には「JAN」や「FEB」などの特殊文字をつかった指定が可能です。?は特定の値を指定しない場合の特殊文字です。
System.scheduleの詳細はこちらです。
System.shceduleをつかって次のバッチをスケジュール登録するとApexバッチ実行後に次のバッチがキュー登録されています。
スケジュール済みジョブを確認すると2015年の一年後、2016年がスケジュール登録されます。
System.scheduleの注意点
Apexクラスをスケジュール登録するとき、ジョブ名が登録済みの場合、エラーとなります。
運用でバッチを2回起動することは無いので大丈夫。と対応する方法も考えられますが、その対応をするとテストクラスで残念な結果が待っています。
このエラーを解決するためにも、既にスケジュール登録済みの場合は登録処理をスキップするようにしておくと安全だと思います。スケジュール登録済みのジョブ情報は『CronJobDetail』オブジェクトにクエリを実行して取得可能です。
SELECT Id, Name, JobType FROM CronJobDetail
ジョブ名を条件にスケジュール登録件数を取得して、1件以上の場合は登録処理をスキップする方法で対応できると思います。
※ビジネスロジック部分は別クラスに実装する方が保守しやすくなると思いますが、別クラスに分けたくない、publicメソッドにしたくない場合は@TestVisibleを宣言してテストクラスから呼び出せるようにしておくとテストがしやすくなります。
スケジュールの重複登録エラーはこんな感じで回避できます。
CronJobDetailオブジェクトの詳細はこちらで確認できます。
サンプルコード
一年後に実行するスケジュールを登録する処理のサンプルです。
関連記事
スケジュールバッチに関する記事です。