これは何?
- Javaにおける日付範囲(Between)の判定する実装について考えたページ
お題目
与えられたある2つの期間(日付)に対して、ある日付が含む又は含まれないかどうかを判定したい。
たとえば、7月20日~7月30日に対して、「8月1日は含まれない」、「7月20日、7月25日、7月30日」は含まれるものとする。
線でたとえると…
---●---------------------●------
7/20 7/30
●は、その日を含むという意味を表すことにする。
実装のやり方
その1
boolean between(LocalDate date){
return (startDate.isBefore(date) && endDate.isAfter(date)) || startDate.equals(date) || endDate.equals(date);
}
その2(よりスマート)
boolean between(LocalDate date){
return !(startDate.isAfter(date) || endDate.isBefore(date));
}
番外編
---○---------------------○------
7/20 7/30
○は、その日を「含まない」という意味を表すことにする。
その1
boolean between(LocalDate date){
return (startDate.isBefore(date) && endDate.isAfter(date));
}
boolean between(LocalDate date){
// 外からくる値をベースに考えるべきではないがシンプル
return date.isAfter(startDate) && date.isBefore(endDate);
}
その2(よりスマート?)
boolean between(LocalDate date){
return startDate.compareTo(date) * endDate.compareTo(date) < 0;
}
boolean between(LocalDate date){
// // 外からくる値をベースに考えるべきではないがパターンとして
return startDate.compareTo(date) * date.compareTo(endDate) > 0;
}
※ 元々のお題目通り(●にする)にしたければ、 >=
や <=
としてあげれば良い。
感想
- 地頭の良さがモロに出てしまうお題目。スマートな実装をできる自分になりたい。
- とはいえ、可読性が下がってしまう点はトレードオフ。(直感的な実装ではないので、読み手を「?」な状態にしてしまう)
- ある意味定番プログラムなのかもしれませんが。
java.awt.Rectangle#intersects
やjava.awt.Rectangle#intersection
などのいわゆる「あたり判定」系のロジックも同じ事が言える気がします。