I18N:夏時間にアプリケーションを対応させる

データのタイムスタンプをどうすべきか

複数国をまたがるような電子商取引システムや、複数国あるいは国内で時差がある地域で使用されるアプリケーションにおいて、トランザクションデータにタイムスタンプを付けて管理する場合があるが、それらのデータにローカル時刻でタイムスタンプを付けてしまうと、時差が考慮されていない(できない)ので、時刻を基にしたデータの比較やそのほかの処理ができなくなってしまう。

特に夏時間のある地域では、夏時間が終了する日には同じ時間が二回あることがあり(たとえば今年のアメリカなら午前2時が二回ある日がある。)、この話を余計に複雑にする。

したがって、アプリケーション内部の業務処理を行うロジックをできるだけわかりやすくするためには、データのタイムスタンプとして利用する時刻はUTCを使用し、人間の目に触れる時点で、その入出力の処理の中でローカル時刻とUTCとの変換をするようにする。

1日が24時間でないことに対応させる

1時間ごとに何らかのデータを記録し、1日分の集計をとるようなアプリケーションがある場合、そのデータを記録するためのスペースは24個分用意すればいいだろうか?もう少し具体的に書くと1時間ごとのデータを記録する先として、レコードの中に時間ごとのデータを格納する24個のフィールドを用意しておけばいいのだろうか。

これは、今の日本に限れば正解である。

しかしながら、前項に書いたように、夏時間がある「地域」では、夏時間の終了日には同じ時間がある。つまりその日は25時間あることになる。逆に夏時間の開始日は1時間飛ばされる時間がある(今年のアメリカであれば午前2時がなくなる)ので、その日は23時間になる。当然UTCでは常に1日は24時間なわけだが、夏時間がある地域ではそのような調整が行われる。

したがって、夏時間によって増減する1日の時間にアプリケーションを対応させるためには、データの格納領域は可変とするか、最大値に合わせるようにしておく必要がある。

また、このように無い時刻や2回ある時刻があるので、帳票フォーマットやデータ入力のフォームにある時刻らんに時刻をあらかじめ書いておいたりしてはいけない。常に動的に変化するものとして考えよう。

ということで、保存する時刻データはUTCで

とりあえず、内部処理に使う時刻はUTCを使うということを心がけておけば、時差や、夏時間がもとで何かとんでもない間違いを起こすということは少なくなると思う。

SQL Serverでの時刻の扱いをどうするか。

SQL Server 2005までの環境であれば、アプリケーション側でUTCに時刻データを変換してから格納すればいい。ストアードプロシージャ等で何らかの処理をする場合には、格納されているデータがUTCであることを前提に処理を考えるようにする。

SQL Server 2008からは、datetimeoffset型という時刻と±14時間のオフセットを持つ時刻型が追加されるので、これをUTCの代わりに利用する方法がある。しかしながら、これに対応する.NETの型が無いし、ADO.NETでの取り扱い方も不明確なので、今はまだこれを前提とする開発はやめておいた方がいいだろう。

なんでUTCなのか

別にUTCでなく、日本時間なら日本時間基準でもいいじゃんというように考えるのも解ります。冷戦期、ワルシャワ条約機構参加国の標準時はGMT(当時)ではなく、モスクワ時間じゃなかったかと。

ただ、どこかのローカル時間を基準にしてしまうと、その地域で夏時間が導入されてしまった時点で、基準としてはいささか問題なってくるだろう。したがって、なんでUTCなのかという問いに対する回答の一つは「UTCに夏時間がないこと、その不変性が保証されているから」となる。

もう一つの実務的な理由としては、ローカル時刻とUTC時刻との変換はたいていのタイムゾーンをまともに扱えるフレームワークやOSには返還のためのAPIがあり、容易に変換処理を実装できるということがあげられる。

日本で夏時間導入とか言っているオヤヂがいますが。。

僕ら日本国に住む人間は国内で時差がないし、夏時間もない幸せな状況にあるので、普段何も気にかけないけど、多国籍企業の業務アプリを作り始めた時点でたぶん、ここに書いたようなことが大変重要になってくる。また、どっかの経団連代表が夏時間導入とか性懲りもなく言っているので、ある日突然夏時間が導入されるかもしれないから、うちは国内オンリーって人もここに書いたことをちょっとだけでも頭の隅に入れて置いていただければと思う。

コメントを残す