1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

3/31と4/1の日付比較しようとしたら同じ日扱いされた恥ずかしい話[Java/Calendar]

Last updated at Posted at 2019-08-12

日付オブジェクトを比較する

入社日と退社日の前後チェックを実装しようと思い、GregorianCalendar(Calendarの具象サブクラス)で以下のように日付オブジェクトを生成しcompareToで比較した。

dateCheck.java

Date march = new GregorianCalendar(2019,3,31).getTime(); // 2019年03月31日(日)
Date april = new GregorianCalendar(2019,4,1).getTime(); // 2019年04月01日(月)
System.out.println(march.compareTo(april)); // 実行結果:0

compareToメソッドの返り値(2つのCalendarオブジェクトで表される時間値(元期からのミリ秒単位のオフセット)を比較)
・参照オブジェクト < 引数オブジェクト → 0未満の値
・参照オブジェクト > 引数オブジェクト → 0より大きい値
・参照オブジェクト = 引数オブジェクト → 0

3月31日より4月1日の方が基準時間からの経過ミリ秒が大きい(日付が後)なので、0未満の値で返ることが望ましい。
しかし、結果は0(同じ)に。

日付を確認してみる

二つの日付オブジェクトをコンソールに出力してみる。

Wed May 01 00:00:00 JST 2019
Wed May 01 00:00:00 JST 2019

どちらも2019年5月1日(水)になっている。ここで「あっ」と気づいた。

月は0から始まる

これを完全に忘れていた。
つまり、3月31日→4月31日、4月1日→5月1日として日付換算される。
4月31日は存在しないが、そんなのお構い無しで経過ミリ秒だけで判断するらしい。

なので、1引いた値を月に設定するとちゃんと思い通りに換算される。

dateCheck.java

Date march = new GregorianCalendar(2019,2,31).getTime(); // 実行結果:Sun Mar 31 00:00:00 JST 2019
Date april = new GregorianCalendar(2019,3,1).getTime(); // 実行結果:Mon Apr 01 00:00:00 JST 2019

System.out.println(march.compareTo(april)); // 実行結果:-1

Calendarクラスの厳密と非厳密モード

ちなみにリファレンスを見てみると、Calendarはカレンダ・フィールドを解釈する際、厳密と非厳密の2つのモードを使用するらしい。

厳密モード:カレンダ・フィールド内に不一致があると、Calendarは例外をスロー
非厳密モード:Calendarはそれ自身が生成する値よりも広範なカレンダ・フィールド値を受け入れる

デフォルトでは非厳密モードになっているが、厳密モードに変更して範囲外の日付をセットしてみると、4月31日を受け入れないようになる。

dateCheck.java
Calendar march = new GregorianCalendar();
Calendar april = new GregorianCalendar();
april.setLenient(false); // 厳密モードに切り替え
march.setWeekDate(2019,3,31); // 成功
april.setWeekDate(2019,3,31); // 失敗:java.lang.IllegalArgumentException: invalid dayOfWeek: 31

以上、めちゃくちゃ恥ずかしいが超超初心者ならあることかも?と思い書き残す。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?