すごく今更感があることですが、地味にハマってしまいました…。
はじめに
日付を文字列にフォーマットするプログラムを書いていたところ、なぜか年数が1900年進んてしまう現象に遭遇しました。そもそもDate
クラスの「年、月、日」をとるコンストラクタは非推奨なので、確かに使わなければ済む話ではあります。しかし、それを知らずにうっかり使うとこうなる、という失敗の一例です。
#現象
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateTest {
public static void main(String[] args) {
int year = 2018;
int month = 5;
int dayOfMonth = 6;
Date todayDate = new Date(year, month, dayOfMonth);
DateFormat dateFormat = SimpleDateFormat.getDateInstance();
System.out.println(dateFormat.format(todayDate));
}
}
この例のように、int
型で与えられた年月日を元にDate
インスタンスを生成し、それをDateFormat
でFormat
すると、
3918/06/06
今年は2018年なのに、3918年となっています。ちょうど1900年進んでいます。
#理由
これは、java.util.Date
クラスの仕様です。
Date (Java Platform SE 8) にも書いてあるのですが、このコンストラクタで受け取るyear
の値は、西暦年から1900を引いた値をとる、という実装になっています。
#そもそも…
詳しい方にとっては周知の事実なのですが、java.util.Date
の年月日を取るコンストラクタは、JDK1.1から非推奨となっています(Date
で検索すると出てくるので、つい使いそうになりますが)。代わりに、java.util.Calendar
でインスタンス化したのち、Calendar#getDate
でDate
インスタンスを得たほうがよいでしょう。
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class DateTest {
public static void main(String[] args) {
int year = 2018;
int month = 5;
int dayOfMonth = 6;
Calendar todayDate = Calendar.getInstance();
todayDate.set(year, month, dayOfMonth);
DateFormat dateFormat = SimpleDateFormat.getDateInstance();
System.out.println(dateFormat.format(todayDate.getTime()));
}
}
2018/07/06
これで、正常に日付が出力されるようになりました。