結論
ミリ秒にして大小判定するのマジおすすめ
※Javaを例にしていますが、どの言語でも同じ話です
※良い子のみんなは、java.util.Dateなんて使わずにJoda-Timeつかうか、Java 1.8以降ならTime APIを使おうネ)
※ただの参考コードです。Dateクラスの非推奨コンストラクタ使うのやめようね
Date nowDate= new Date();
// 2020/4/1 00:00:00 ~2020/4/30 23:59:59 の場合に「キャンペーン期間中だよ」と出力
if (nowDate.getTime() >= new Date(2020, 3, 1, 0, 0, 0).getTime()
&& nowDate.getTime() < new Date(2020, 4, 1, 0, 0, 0).getTime()) {
System.out.println("キャンペーン期間中だよ");
}
言い訳
皆さんは、Javaの日付の判定、どうされていますか?
java.util.Dateクラスを利用する場合、afterメソッドやbeforeメソッドを使っていますか?
Joda-TimeやTime APIでも、似たようなメソッドありますよね?
でも、正直私はそのメソッドを見ただけでは「引数が未来なんだっけ?過去なんだっけ?指定された日付は含むんだっけ?含まないんだっけ?」というのを即時に判断出来ません。(アホですね)
JavaDocを見るとそれぞれこう書かれています。
(Java 1.8のJavaDocから引用)
- after
この日付が、指定された日付より後にあるかどうかを判定します。
- before
この日付が、指定された日付より前にあるかどうかを判定します。
つまり、どちらも「指定された日そのもの」は含まないわけです。
英語が得意な方は、afterやbeforeが「含まない」という意味だと理解しているかもしれないですが、
僕は知りませんでした。
よくやるポカとして、
「2020年4月1日の00:00:00~2020年4月30日の23:59:59までをキャンペーンの申し込み期間としよう!」とした場合に
Date nowDate = new Date();
if (nowDate.after(new Date(2020, 3, 1, 0, 0, 0))
&& nowDate.before(new Date(2020, 4, 1, 0, 0))) {
System.out.println("キャンペーン期間中だよ");
}
こんな風にしちゃって、「日付変わった瞬間は申し込み出来ねーじゃん!!!!!」っていうバグを作り込んじゃいます。
(まあ、その1秒を良しとするかどうかはプロジェクト次第ですが)
だから、数値型にしちゃって大小比較したほうが間違いが無いよね。っていう話でした。