2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JAVAでn営業日後を求める

Posted at

JAVAでn営業日後を求める

業務ロジックを書いていると、n営業日後の日付が必要になることがあります。
(n営業日以内に処理を行わない場合アラートなど)
が、これを求めるのは結構面倒です。
休日が土日だけなら簡単に計算できますが、祝日には決まった法則がありません。
自システム上にマスタを作成して管理するか、外部から情報を取得する必要があります。

前者は自分でマスタを管理する必要があり面倒なので、今回は後者の手段で営業日を確認するクラスを作ってみました。

できたもの


@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class BusinessDayApiAccessorServiceImpl implements BusinessDayApiAccessor {

	private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("uuuuMMdd");

	private final OkHttpClient client;

	@Override
	public LocalDate getBusinessDayAfter(LocalDate baseDate, int days) {
		return getBusinessDay(true, baseDate, days);
	}

	@Override
	public LocalDate getBusinessDayBefore(LocalDate baseDate, int days) {
		return getBusinessDay(false, baseDate, days);
	}

	private LocalDate getBusinessDay(boolean isNext, LocalDate baseDate, int days) {
		if (days == 0) {
			return baseDate;
		}
		return getBusinessDay(isNext, sendRequest(isNext, isNext ? baseDate.plusDays(1) : baseDate.minusDays(1)),
				days - 1);
	}

	private LocalDate sendRequest(boolean isNext, LocalDate baseDate) {
		HttpUrl httpUrl = new HttpUrl.Builder().scheme("http").host("s-proj.com").addPathSegment("utils")
				.addPathSegment("getBusinessDay.php").addQueryParameter("kind", isNext ? "next" : "prev")
				.addQueryParameter("date", baseDate.format(DATE_FORMATTER)).build();
		Request request = new Request.Builder().url(httpUrl).get().build();
		try (Response response = client.newCall(request).execute()) {
			String resultBody = response.body().string();
			return LocalDate.parse(resultBody, DATE_FORMATTER);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public boolean isBusinessDay(LocalDate date) {
		return sendRequest(true, date).isEqual(date);
	}
}

解説

国民の祝日チェックさんの公開されている国民の祝日APIを営業日判定の元ネタとして利用します。
このAPIは対象の日付が営業日だったらその日付を、営業日ではなかった場合は次または前の営業日を返してくれます。
よって、nに達するまで1日ずつ日付をずらしながら、APIを叩くメソッドを実行すればn営業日後(あるいは前)の日付を求めることが出来ます。
なお、APIを叩くのにOkHttpを利用しています。

注意点

外部へのAPIアクセスを挟む上に再帰ロジックなのでnの値は多くても10前後までが現実的です。
100営業日後とかを求めようとすると大変なことになります。(業務上あまりないとは思いますが)
万が一必要な場合は別な手段を使ったほうが無難です。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?