読者です 読者をやめる 読者になる 読者になる

潜伏バグからのロングフリーズ

Javaっぽいエンジニアの徒然草

直感的で一目で分かる日付の大小比較

Java

これまでDate型の大小比較はDate#compareToを利用していました。

 

これです。

public int compareTo(Date anotherDate)

 

処理結果は、次のようになります。

引数 Date がこの Date と等しい場合は値 0。

この Date が引数 Date より前の場合は 0 より小さい値。

この Date が引数 Date より後の場合は 0 より大きい値。

 

具体例として、

AAA.compareTo(BBB)

の形式だとすると、

AAA == BBB の場合 戻り値は0となる

 ∴(Java) 0 == AAA.compareTo.BBB

 

AAA <  BBB の場合 戻り値は0より小さくなる

 ∴(Java) 0 > AAA.compareTo.BBB

 

AAA >  BBB の場合 戻り値は0より大きくなる

 ∴(Java) 0 < AAA.compareTo.BBB

 

AAA <= BBB の場合 戻り値は0以下となる

 ∴(Java) 0 >= AAA.compareTo.BBB

 

AAA >= BBB の場合 戻り値は0以上となる

 ∴(Java) 0 <= AAA.compareTo.BBB

 

となります。

が、これは本当に分かりにくいのです。

ぱっと見どっちが大きいのか混乱してしまいます。

Before, After methodを用いる手もあるのですが、

これを使うとイコールを含んでいるのか含まないのか分からなくなる時があります。

もちろん、全て正しく記憶しておけば良いのですが...

 

もっとこう、プログラマがぱっと見て分かる形はないものか。

そんなことを考えながら実装を眺めていると、目から鱗の真実に出くわしました。

 

Date#compareTo()

→ 中でlong変換して比較している!!

 

つまり、こういうことです。

3変数 Date start, Date end, Date target があるときに、

start<=target<=end であることを判定したい状況を例にします。

 

■compareToを用いた場合

実に分かりにくいです。

if (0 >= start.compareTo(target) && 0 >= target.compareTo(end)) {

    // start <= target <= end である

}

 

■getTime()してlongで比較する場合

ただの数値の大小比較! 分かり易い!!

if (start.getTime() <= target.getTime() && target.getTime() <= end.getTime()) {

    // start <= target <= end である

}

 

【結論】

無理にDate型で頑張って比較せずに、

素直にlong変換して比較した方が直感的で分かり易い。