JavaのDateクラスをコンストラクタから生成した時に、年が指定したのと違う値になったので調べてみたメモ。
Dateの年が1900大きくなる
先日とあるAndroidアプリの開発中にDateクラスを使う機会がありました。特に意識もせずにDateのコンストラクタを使ってDateオブジェクトを生成して使ってたんですが、どうも動作がおかしいのでデバッグしてみると、なんと年の値が指定した値より1900も大きくなってるじゃーないですか!なんだこれ!
Dateのコンストラクタは非推奨!
今回使ったのは年・月・日・時・分までを指定するコンストラクタです。
1 |
Date date = new Date(2014, 8, 26, 13, 0); |
こんな感じでDateクラスを生成すると、2014/09/26/13:00を表すDateオブジェクトが生成されるものと思っていたのですが、実際は年の値が3914になっていました。
リファレンスを調べてみると、パラメータの説明として確かにyear – 年から 1900 を引いたものと記載されていました。うーん、なるほど。とりあえず原因はわかったけど他の言語のDateでこんなんあったっけ…。
しかしそれ以上に気になる記述は「JDK1.1から非推奨」というもの。どうも引数なしのコンストラクタ以外、現在は非推奨だそうです。標準クラスのコンストラクタが非推奨だと?どういうことなの?と思って調べてみると、こちらの記事でその歴史的経緯について考察されていました。なにやら複雑な経緯を辿っているみたいですね。全然知りませんでした。
結論:Calendarクラスを使う
ということで公式リファレンスに書かれているように、日付操作をする場合はCalendarクラスを使いましょう。現在日時を取得する以外の目的でDateクラスをnewすることは避けた方が良さそうです。
任意の日時のDateクラスを生成したい場合は、Calendarクラスに任意の日付を設定してそこから取得するのがJavaのお作法ということなんですね。実際のコードは以下のような感じになります。
1 2 3 |
Calendar calendar = Calendar.getInstance(); calendar.set(2014, 8, 26, 13, 0); // 月は0から始まるので注意! Date theDate = calendar.getTime(); // 2014/9/26/13:00を表すDateオブジェクトが取得できる |