質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.06%

  • Java

    11788questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

[Java]日付の比較をしたい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,698

k499778

score 496

Javaで日付の比較をしたいです。
ただしDBの値が「2017-05-26」の形式なので本日の日付と比較するには時分秒を切り捨てなければいけません。
以下リンクのように
日付だけを比較
DateUtils.truncateを使えばできそうですが、DateUtilsクラスをインポートできない環境でした。

他にいい方法があればよろしくお願いします。

現在の状況。これだと同じ日付でも時分秒が異なるとfalseになってしまうときがある。

public boolean getFlg() throws ParseException {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = sdf.parse("2007-01-01");
Date endDate = sdf.parse("2017-05-26");

Date now = new Date();
int diff1 = now.compareTo(startDate);
int diff2 = endDate.compareTo(now);

if (diff1 >= 0 && diff2 >= 0) {
    return true;
}
    return false;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+3

切り捨てる必要はありません。
「2007/01/01から2017/05/26の間」であることを判定するには、
「2007/01/01 00:00:00(日本時間)以降、2017/05/27 00:00:00(日本時間)より前」であることを判定すればいいのです。
26日ではなく27日を使うのがポイント。だから期末日を1日進めて使うようにしてみてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/26 08:43

    startDateも同様にマイナス1するのでしょうか?
    startDate,endDateはDBの値なのでできればいじりたくないのですが、nowをいじるとどうなりますでしょうか?

    キャンセル

  • 2017/05/26 10:41

    endDateに1日足す目的は、2017-05-26 **:**:**に対応するためです。
    これは*部が何時何分何秒であろうと2017-05-27 00:00:00の前になり、
    日付を過ぎた2017-05-27 **:**:**の時刻は2017-05-27 00:00:00以降になります。つまり、
    2017-05-26 **:**:** < 2017-05-27 00:00:00 <= 2017-05-27 **:**:**
    となるので、この条件で2017-05-26までの日付を判定できるのです。
    逆にstartDateはいじる必要はありません。

    キャンセル

  • 2017/05/26 18:09

    回答ありがとうございます。
    そうでしたか。いろんな観点を学ぶことができました。ありがとうございました。

    キャンセル

+2

いくつか方法を提示します。お好きなものをお使いください。

  • すべてCalendarに変換する
    (yubaさんの提案を織り交ぜています)
public boolean getFlg() throws ParseException {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Date startDate = sdf.parse("2007-01-01");
    Date endDate = sdf.parse("2017-05-26");

    Calendar from = Calendar.getInstance(),
             today = Calendar.getInstance(),
             to = Calendar.getInstance();
    from.setTime(startDate);
    to.setTime(endDate);
    to.add(Calendar.DATE, 1);  //終了日時を翌日に

    int diff1 = today.compareTo(from);
    int diff2 = to.compareTo(today);

    return diff1 >= 0 && diff2 > 0;
}
  • getTime()で得られるlong値で比較。その際に終了日時のほうに1日相当のミリ秒を加算する
public boolean getFlg() throws ParseException {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    long startDate = sdf.parse("2007-01-01").getTime();
    long endDate = sdf.parse("2017-05-26").getTime() + 24L * 60L * 60L * 1000L;
    long now = new Date().getTime();

    return startDate <= now && now < endDate;
}
  • 逆転の発想。文字列に変換して比較する
    日付の後先と文字列化した日付の後先は一致する
public boolean getFlg() {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String startDate = "2007-01-01";
    String endDate = "2017-05-26";
    String now = sdf.format(new Date());

    int diff1 = now.compareTo(startDate);
    int diff2 = endDate.compareTo(now);

    return diff1 >= 0 && diff2 >= 0;
}
public boolean getFlg() {

    LocalDate startDate = LocalDate.parse("2007-01-01");
    LocalDate endDate = LocalDate.parse("2017-05-26");
    LocalDate now = LocalDate.now();

    int diff1 = now.compareTo(startDate);
    int diff2 = endDate.compareTo(now);

    return diff1 >= 0 && diff2 >= 0;
}

今更追加(17/09/17)。

  • 日付比較するメソッドを作る
public boolean getFlg() throws ParseException {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Date startDate = sdf.parse("2007-01-01");
    Date endDate = sdf.parse("2017-05-26");

    Calendar from = Calendar.getInstance(),
             today = Calendar.getInstance(),
             to = Calendar.getInstance();
    from.setTime(startDate);
    to.setTime(endDate);

    return compareByDate(from, today) <= 0 && compareByDate(today, to) <= 0;
}

public static int compareByDate(Calendar c1, Calendar c2) {
    int i = Integer.compare(c1.get(Calendar.YEAR), c2.get(Calendar.YEAR));
    if (i != 0) return i;
    return Integer.compare(c1.get(Calendar.DAY_OF_YEAR), c2.get(Calendar.DAY_OF_YEAR));
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/26 18:10

    回答ありがとうございます。
    こんなにもたくさん!ご提示頂きありがとうございます。
    1度自分で噛み砕いて自分のものにしたいと思います。感謝いたします。ありがとうございました。

    キャンセル

  • 2017/05/26 18:48

    このコードでつっこみどころがあると、「一日後」の表現の仕方ですね。
    24時間分のミリ秒を加算するやり方は、夏時間制度が導入されたときにおかしくなります(あり得ない? いやいや、今の立法なら明日どんな法律ができてるかわかりません)。翌日を意味するためには23時間もしくは25時間進めないといけない日というのが出てきますから。

    スマートさは薄れるのですがCalendarで年・月・日に分解して日を1増やしたCalendarを作り直してそこからタイムスタンプを取ってDateに、というのが頑強なやり方になります。

    キャンセル

  • 2017/05/26 19:47

    そうなると1つ目とほぼかぶるので2つ目はボツですね

    キャンセル

  • 2017/05/26 20:05

    あっ一つ目をちゃんと開いたらちゃんとそうなっていました。なんか開かないまま読んでいて2つめと混同していました。

    キャンセル

0

全くお薦めしませんが、日付文字列の書式が決まっているなら数値で比較してはどうでしょう。

String d1 = "2017-01-01";
String d2 = "2017-05-26";
d1 = d1.replaceAll("-", "");
d2 = d2.replaceAll("-", "");
Integer d1i = Integer.parseInt(d1);
Integer d2i = Integer.parseInt(d2);
System.out.println(d1i.compareTo(d2i));


しかしながら他の方も記載されていますが、期間判定とかを行うならCalendarを使った方がいいと思いますよ。以下のコードは適当ですが、時分秒ミリ秒を固定で初期化してもいいわけですし。

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Date startDate = formatter.parse("2007-01-01" + " 00:00:00.000");
Date endDate = formatter.parse("2017-05-26" + " 00:00:00.000");

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/26 11:44

    現在時刻の処理が入っていないので全く意味のないコードになっています。

    キャンセル

  • 2017/05/26 11:55

    私は『yyyy-MM-ddの部分だけで同一日かどうか判断したい』という意図だと理解したので上記のように回答したのですが…まあ受け取り方次第ということで。

    キャンセル

  • 2017/05/26 18:10

    回答ありがとうございます。
    私の方でも1度確認してみます。
    ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.06%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Java

    11788questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。