SimpleDateFormatとTimeZone

Javaで日付をフォーマットをかけて、出力したとき、何故か時刻が9時間ずれた。
よくあるタイムゾーンの設定かと思い、staticイニシャライザで設定しみた。


static{
Locale.setDefault(Locale.JAPAN);
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Tokyo"));
}
これで問題なかろう、と出力してみると、やっぱり9時間ズレてる。
SimpleDateFormatオブジェクトは生成コストが高いので、static finalとして、クラス変数として生成。でも、日付は正しい時刻みたい。
おやおや?どういうこっちゃ?
どうやら、DateFormatにもタイムゾーン設定があるらしく、フォーマットをかける時は、こちらが優先されるみたい。
なんだかめんどさいぬー。
ちなみに、static finalで定義しているので、staticイニシャライザのデフォルトタイムゾーン設定変更が走る前の状態で、インスタンスが生成されてしまっていた。
staticイニシャライザ内でDateFormat.setTimeZone()を呼べばOK!!

検証コード


import java.util.*;
import java.text.*;

public class DateTest{

private static final DateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
public static void main(String[] args){
System.out.println("");
System.out.println(Locale.getDefault());
System.out.println(TimeZone.getDefault());
System.out.println(Calendar.getInstance().getTime());
System.out.println(format.format(Calendar.getInstance().getTime()));

System.out.println("");
Locale.setDefault(Locale.JAPAN);
System.out.println(Locale.getDefault());
System.out.println(TimeZone.getDefault());
System.out.println(Calendar.getInstance().getTime());
System.out.println(format.format(Calendar.getInstance().getTime()));

System.out.println("");
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Tokyo"));
System.out.println(Locale.getDefault());
System.out.println(TimeZone.getDefault());
System.out.println(Calendar.getInstance().getTime());
System.out.println(format.format(Calendar.getInstance().getTime()));

System.out.println("");
format.setTimeZone(TimeZone.getTimeZone("Asia/Tokyo"));
System.out.println(Locale.getDefault());
System.out.println(TimeZone.getDefault());
System.out.println(Calendar.getInstance().getTime());
System.out.println(format.format(Calendar.getInstance().getTime()));
}

}

実行結果

$ java DateTest

en_US
sun.util.calendar.ZoneInfo[id="Etc/UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
Wed Jul 10 13:38:29 UTC 2013
2013/07/10 13:38:29

ja_JP
sun.util.calendar.ZoneInfo[id="Etc/UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
Wed Jul 10 13:38:29 UTC 2013
2013/07/10 13:38:29

ja_JP
sun.util.calendar.ZoneInfo[id="Asia/Tokyo",offset=32400000,dstSavings=0,useDaylight=false,transitions=10,lastRule=null]
Wed Jul 10 22:38:29 JST 2013
2013/07/10 13:38:29

ja_JP
sun.util.calendar.ZoneInfo[id="Asia/Tokyo",offset=32400000,dstSavings=0,useDaylight=false,transitions=10,lastRule=null]
Wed Jul 10 22:38:29 JST 2013
2013/07/10 22:38:29