擬似時計クラスの動作確認
バッチなどに用いる擬似的な時計を設定したい
業務よりの話になるが、バッチを実行する時に固定の時間指定は比較的容易だ。
しかし、バッチで一括データ更新をする場合、全レコードの時刻が同じだとデータの整合性が取れないことがあった。
その場合、時間指定した上でその時間を動かしたい。
そこでどういう風に書けばいいのだろうと思って、擬似的な時計クラスを作成して、動作確認したので、メモを残す。
ステートフルなMockTimeクラスをまず作成。
public class MockTime {
private int second = 0;
public void tick() {
second++;
}
public int getSecond() {
return second;
}
}
定期的にMockTimeクラスでMockTimeの秒数足していく。
public class TimeKickTask extends TimerTask {
private MockTime mockTime;
public TimeKickTask(MockTime time) {
mockTime = time;
}
public void run() {
mockTime.tick();
}
}
動作確認用のメインクラス
package com.example.democlock;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Timer;
public class DemoClockApplication {
public static void main(String[] args) throws InterruptedException {
// ゾーン指定(Asia/Tokyo)
ZoneId zoneId = ZoneId.systemDefault();
// 日付と時刻指定
ZonedDateTime zonedDateTime = ZonedDateTime.of(2017, 6, 27, 22, 0, 0, 0, zoneId);
// 指定したTimeゾーンと時刻でClockクラスのインスタンス生成
Clock clock = Clock.fixed(zonedDateTime.toInstant(), zoneId);
// Timer設定
Timer timer = new Timer(true);
MockTime mockTime = new MockTime();
// 1mごとにMockTimeの値がインクリメントされる
timer.scheduleAtFixedRate(new TimeKickTask(mockTime), 1, 1);
for (int i = 0; i < 1000; i++) {
System.out.println("current time:" + LocalDateTime.now(Clock.offset(clock, Duration.ofSeconds(mockTime.getSecond()))).
format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
Thread.sleep(10);
}
}
}
実行結果
current time:2017-06-28T01:03:29
current time:2017-06-28T01:03:39
current time:2017-06-28T01:03:50
current time:2017-06-28T01:04:02
current time:2017-06-28T01:04:14
Process finished with exit code 0
まとめ
Timer使ったら、それっぽい指定した時間を動かす動作ができた。あくまでそれっぽく時計を進めているだけなので、注意。
リポジトリ
https://github.com/vagivagi/demo-clock/tree/0.0.1
追記
改訂版書いた。
https://vagivagi.com/entries/12