- 2007-10-04 (木)
- 技術
Javaのバージョン :JDK1.4.2_08
Oracleのバージョン :Oracle 9i
多言語対応システムを組む際には、入力された日付を各現地時間としてDBに登録する場合がある。
例えば画面から入力された日付をAmerica/Los_Angelesの時間として登録する場合には、
from_tz(to_timestamp('2007/10/22 00:00', 'yyyy/mm/dd hh24:mi'), 'America/Los_Angeles')
とfrom_tz関数を使用して現地の時間ですよ~と指定する必要がある。
今回ボクがやろうとしたことは、
Java側で入力した日付をUTCに変換する。
America/Los_Angelesだとした場合には、入力された日付に対してTimeZone.getRawOffset()をすることによってUTCに変換される。
そしてUTCに変換された日付をUTCとしてDBにInsertする。
from_tz(to_timestamp('2007/10/22 00:00', 'yyyy/mm/dd hh24:mi'), 'Etc/GMT')
これでうまくいくとにらんでいたのですが、以下のとおりJavaとOracleでタイムゾーンが一致しない場合がある。
- タイムゾーンの個数の不一致
- タイムゾーンをUTCにした場合の時間のズレ(JavaでAmerica/Los_Angelesは-8時間、OracleでAmerica/Los_Angelesは-7時間)
これはOracle10gから解消されているようで、10gではAmerica/Los_Angelesは-8時間となっているためJavaと一致する。
このことにより、もし多言語対応で入力された日付をUTCに変換しようとすることがある場合は極力DBのタイムゾーンに任せる方法がよいだろう。
- 入力された日付はJava側でUTCにしない
- from_tz関数を使って現地のローカルタイムゾーンを指定してInsertする
これを守っておけば常にOracleのタイムゾーンを使用してInsertをかけるので、JavaとOracleのミスマッチ現象は回避できる。
このような状況はなかなかなる機会がないと思うが、もしこのメモが誰かの役に立ったとしたらうれしいです。
また今回Java側でUTCに変換したプログラムも公開しておく。
基本は使わないほうがよいが、何かの参考までに。
■Javaで日付StringをUTCTimestampに変換する方法
public static Timestamp getUTCTimeStamp(String date, String zone) throws ParseException{
// 文字列型日付をTimestamp型に変換する。
SimpleDateFormat dateFmt = new SimpleDateFormat(Constant.JAVA_DATE_FORMAT, Locale.US);
Timestamp stamp = new Timestamp(dateFmt.parse(date).getTime());
// 現地のタイムゾーンに設定する。
TimeZone tz = TimeZone.getTimeZone(zone);
dateFmt.setTimeZone(tz);
stamp.setTime(stamp.getTime() - tz.getRawOffset());
return stamp;
}
■関連資料
・Javaの道:日付・時刻(4.TimeZoneクラス)
・Oracle Real-Time Collaborationのタイムゾーン
・Java 2 Platform SE 1.3: クラス TimeZone
【関連する記事】
- Newer: Eclipseでタブを移動するショートカット
- Older: Web2.0提唱者 ティム・オライリー氏のインタビュー
Comments:0
Trackback:0
- TrackBack URL for this entry
- http://hisasann.com/cgi-bin/mt/mt-tb.cgi/495
- Listed below are links to weblogs that reference
- JavaとOracleのタイムゾーンミスマッチを解消する方法 from HouseTect, JavaScripter Blog

