Edited at

期間のマッチング

More than 3 years have passed since last update.

業務システムでよくある要件で、例えば、


深夜の時間帯のご利用は30%OFFにします


みたいな話で、料金計算をするとき、割引時間帯に利用時間範囲が入っているかどうか判定し、割引率を算出します。

よくよく考えればシンプルな話ですが、毎回、図を書いて考えている気がするのでまとめておきます。


期間のマッチングのパターン

ルールの開始時刻をRs、終了時刻をRe、判定対象データの開始時刻をTs、終了時刻をTeとします。

image

当然ながら、Rs ≦Re および Ts ≦Te が成立します。

ここで2つの期間の交わり方のパターンは、以下のとおり6パターン存在します。

image

さて、割引の適用ルールには、実業務においてはこれらのパターンの組合せで以下の3つがありうるかと思います。それらについて、条件式の書き方をまとめます。


1. 割引期間内に利用期間がすっぽり収まる

この真ん中のケースです。

image

これを素直に書くと、以下のようになります。

if (rs <= ts && ts <= re && rs <= te && te <= re) {

// 30%OFFの処理
}

ちなみに前置記法を使うと自然な感じで書けます。

(if (and (<= rs ts re) (<= rs te re))

;; 30%OFFの処理
)

ただ、これはN/Aの領域を利用すると、以下のように書けることがわかります。N/Aのうまい扱い方については『エスイーが要件定義でやるべきたったひとつのこと(実践編)』を参照して下さい。

if (ts >= rs && te <= re) {

// 30%OFFの処理
}

image


2. 割引期間に利用期間が少しでも入っていればよいケース

これは以下の4パターンです。

image

したがって、条件式は以下のようになります。

if (ts <= re && te >= rs) {

// 30%OFFの処理
}


3. 利用開始または利用終了が割引期間に入っている、またぎはだめなケース

またぐケースを許されない場合は、あまりキレイにはいきません。

image

利用開始または終了が割引期間に入っていることを条件式にします。(ま、字面通りですね)

image

if ((rs <= ts && ts <= re) || (rs <= te && te <= re)) {

// 30%OFFの処理
}


まとめ

業務要件で似たようなものが出てきた際にはどうぞお使いください。