google app engine (java) の日時処理で大苦戦

# google app engine カテゴリってよりか、Java servlet というカテゴリな気もしますけれども…(ぉ ^^;

Java Servlet で、日付処理って一般的(?)にはどうするんですかねぇ…。

Servlet 内部では UTC なので、そのまま DateFormat で文字列化したモノを日本人が見ると 9時間足りないモノになっちゃうんですよね。

なので、日本に限らずそのロケールに合った時間を表示したいー……って時に超こまりんぐ。

ダメだった… orz

※ダメな例

// request -> ブラウザからのリクエスト
Locale   myLocale  = request.getLocale();
String   myCountry = myLocale.getDisplayCountry(Locale.US); // どこのお国の方かしら?
TimeZone myZone    = TimeZone.getTimeZone(myCountry);

int        DEF        = DateFormat.DEFAULT;
DateFormat dateFormat = DateFormat.getDateTimeInstance(DEF, DEF, myLocale);
dateFormat.setTimeZone(myZone); // お国のTimeZoneを設定

Date   date = new Date();
String fmt  = dateFormat.format(date);
out.println(fmt);

とまぁ、割と力業コードだった故に問題が発生してしまいました…


どうしてこうなった?

DateFormat.getDateTimeInstance() の引数なしバージョンでフォーマットしてみたところ UTC (GMT?) でフォーマットされてしました。 んじゃぁ、Locale 指定版を使えばそのロケールの時間が増減されてフォーマットされるだろう! …とおもったら そんなことは無かったという(ぉ orz*1

とはいえ、DataFormat.setTimeZone()タイムゾーンを適切に指定すれば増減してくれる事がわかったので、んじゃぁ Locale から TimeZone 取ろうよ! …とした結果、こんなコードになりました。

日本の場合は myCountry に "Japan" が入って、getTimeZone() がたまたま正常に動いてくれていたんですが、ブラウザの言語を [ko] - 韓国にすると "South Korea" が返り getTimeZone() が GMT を返して来てしまうと言う…ギギギギギギ…

# …んまぁ、getTimeZone() へは「国と地域」を指定するのが正しいっぽいので、根本的に間違ってるといえば間違ってるんですけど…(ぉ ^^;



ちなみに「Locale を使って Calendar 作って、そこから getTimeZone() すりゃいいんじゃねーの?」という話も あった んですが、コレもGMTが取れるだけした…。


思うところ

ブラウザからは「言語」と「国(?)」しか情報送ってこないんだから、詳細な地域までは判定できない気がします。en-USだったら、本土もあればアラスカもあればハワイもある。 おそらくそれぞれ標準時が違うハズ。たぶん。(ぉ

…とはいえ、国がわかればその国のもっとも主となる timezone で時刻を offset したい所 → Locale#getISO3Country() で取れる文字列と TimeZone#getTimeZone() で目的の TimeZone が取れる文字列を map するテーブルを作る → えええそこまでしなきゃアカンの? なんか別に手法あるんちゃうの!? ← いまココ

という所で詰まってます… というより、なんかもう諦めモード(ぉ

どうせ身内しか使わないんだから、TimeZone を JST 固定でもいいよねもう… 「80:20の法則」とか言って逃げてもいいよね…



…ちなみにこの問題に悩んで早2日目(ぉ orz

*1:おそらく時間のオフセット操作はせずに、文字列化する時の言語を指定するだけなんですかね。「金曜日」と表示したり「Fri」と表示したりを変化させるだけっていう