.NET Framework における時差情報(サマータイム)の取り扱い


実は先日、8/1 に社内で異動しまして、18 年間続けてきたコンサルタントからクラウドソリューションアーキテクトにロールチェンジしました。さてこの blog もタイトルを変えるべきかどうなのか……とかまったり考えていたら、ここ数日、びっくりするような話題が飛び込んできました。

2020 年のオリンピックに向けて、限定的(または恒久的)にサマータイムを導入する、というもの。話を聞いたときに耳を疑ったのですが、いやもう絶対に不可能だろう、と私も思いました;。上記に取り上げた立命館大学の上原さんのスライドは非常によくまとまっていて、ホントこれ、と思いましたが、一方で Windows をはじめとするコンピュータシステムでそもそもサマータイムがどのような取り扱いになるのかを知らない人は多いのでは?、と思います。

実はずいぶん昔に国際化対応アプリケーションの開発方法を調べたことがあり、そのときにタイムゾーン(時差情報)をどのように取り扱うのか、をまとめたことがあります。おそらく皆様の参考になるのでは、と思いますので、若干手直しして情報共有してみます。10 年以上前の資料なので、画面のスナップショットがまさかの XP や Vista(!)だったりするのはご容赦、なのですが、考え方は特に変わっていないので、今でも普通に通用する内容かなと思います。(もし何か変わっているところがあったら教えていただけると嬉しいです;。)

 

ちょっと長いスライドなので、夏時間(サマータイム)という観点から要点を抜き出すと、以下の 2 つがポイントです。

① Windows OS 上では、夏時間はタイムゾーンの変更として取り扱われる (p.10)

夏時間に入る=別の国のタイムゾーンに移動したのと同じようなこととして扱われます。イメージとしては、日本国内にいながら、時差のある国へ海外旅行に行ったのと同じような取り扱いになる、と考えるとわかりやすいかと思います。(なお、夏時間などのタイムゾーン情報はレジストリ情報として管理されており、Windows Update によりメンテナンスされています。なので本資料ではカバーしていませんが、 .NET Core で作ったアプリを Linux 上で動作させたりする場合にはまた別の注意が必要になってきます。)

② DateTime 型の加減算処理を行う際は、必ず UTC を介して行う (p.35, 36)

.NET Framework 上で日付をプログラミングする際、DateTime 型でプログラミングされている方が多いと思いますが、DateTime 型はオフセット値(UTC からの時差)を持つことができません。DateTime 型は、「見た目の数値」をそのまま加減算処理してしまうため、夏時間前後でのオフセット値の変化に対応できません。このため、DateTime 型で加減算処理を行う場合には、必ず UTC を介して計算する必要があります。(ちなみにこの問題に対応するために導入されたのが DateTimeOffset 型です。)

アメリカでは国内に主に 4 つのタイムゾーンがある上に夏時間まであるため、プログラミングを行う際にタイムゾーンを考慮したプログラミングを行うのは当然なのですが、日本国内の場合、長らく単一のタイムゾーンしかなかったため、タイムゾーンを考慮した形で設計・実装・テストされているシステムは非常に少ないでしょう。正直なところ、今の状況で夏時間が導入された場合のことを考えると、日本の開発の実情を知る自分としてはかなりぞっとします。(「うちのシステムは夏時間が導入されても大丈夫です!」と言える国内開発者はどれだけいるのだろうかと....;)

# ネットを見ていると、システムの時刻変えればいい、みたいに単純化されている人もいるのですが、スタンドアロンで動く時計みたいなものと、システム間で連携することが前提になっているシステムとでは全く違うんですよね;。
# 例えば DB に書かれた時刻や電文に乗っかってくる時刻が JST なのかサマータイムなのかは大問題で、自分のシステムがちゃんとサマータイム対応していたとしても、相手先のシステムから 1 or 2 時間ずれた時刻が送られてきた瞬間に業務矛盾を起こすケースとか、そういうぞっとするケースが考えられまくるんですよね。
# 本来はこういう問題を避けるために、すべて UTC ベースで処理するのが基本なんですが、ひと昔前のシステムだと UTC で時刻を扱っているケースなんてほとんどないのではないかと思うのですが;(もしかしたら今でもそういうシステムが多数なのかも;)。

2020 年に併せた夏時間の導入はあまりにも無茶すぎる、とエンジニア的な観点からは思いますが、とはいえこれからの IT エンジニアにとって、タイムゾーンや夏時間(サマータイム)を理解し、国際化対応アプリケーションを作る(海外でも動作するアプリを書く)ことは必須かと思います。この資料が、IT エンジニアのみなさんにとって、タイムゾーンや夏時間(サマータイム)を理解する一助になれば幸いです。


Comments (1)

  1. nakama より:

    なんか週末にかなりバズっていたようで、取り上げていただいた皆様、ありがとうございました。m(_ _)m いやホントに無理ゲーですよね、これ;。

    いくつか質問もあったので、フォローさせてください。

    > https://twitter.com/ledsun/status/1028187063063957504
    > 夏時間はタイムゾーンなのか。すると、システム管理者は、ある日、全管理端末に、ActiveDirectoryか何かで、夏時間のタイムゾーンを流しこむのかな?

    夏時間の情報はレジストリに保存されており、OS のパッチとしてこの情報が更新されるようになっています。なので Windows Update を適用すれば、夏時間のタイムゾーン情報が追加されます。例えばこんな感じです。
    https://support.microsoft.com/ja-jp/help/3162835/june-2016-dst-and-time-zone-update-for-windows

    > http://b.hatena.ne.jp/entry/369094918/comment/infobloga
    > ちなみに、RDBのDATETIME型は、アンパック10進数でローカルタイムそのまま持ってるからな / ただ、それは頑張ればどうにかなる。前も書いたが最大のカオスは予約時刻、閉店時刻など本質的にローカルタイムベースの時刻。

    RDBMS もヤバいですが、最もヤバいのは、

    ・分散しているシステムやアプリのどこか一か所でも JST/JDT の解釈がずれた瞬間に動作不具合が起きる可能性が出る
    ・この手の動作不具合が起きたときに、どこのコードがミスっているのかをデバッグするのが恐ろしく大変

    というところだと思っています。A システムでは 13 時にお金を振り込んだはずなのに B システムでは 14 時に振り込んだことになっていて、結果的に入金が間に合わなくて何か差し止められた、とか起こったりするとシャレでは済まなくなります;。(こういう問題を避けるためにオフセット表記があります。オフセット表記があれば、JST/JDT などどの解釈で時刻が書かれているのかわかります。)

    > http://b.hatena.ne.jp/entry/369094918/comment/s_tsukiyama
    > Windows UpdateでJDT(日本夏時間)が追加された時、過去のデータの時間表示はどうなるのか、私、気になります! / 「8月だからJDT表示」か「18年8月はJSTで表示」か。

    結論から言うと、「18年8月はJSTで表示」が正しいです。先ほど取り上げた Windows Update の情報を見るとわかるのですが、レジストリ上の夏時間情報は、以下の組み合わせで書かれています。

    ・何年何月何日何時何分から何年何月何日何時何分までが夏時間なのか
    ・夏時間になると、どのタイムゾーンに変わるのか

    要するに、2019/07/01~2020/08/31 までが JDT に変わる、という情報の持ち方をするので、この期間以外の日時は夏時間の影響を受けないようになっています。なので 2020 年までの期間限定導入であっても、Windows OS は正しく動作することができます。やったね。(そういう問題じゃない)

    ちなみに余談ですが、そもそも System.DateTimeOffset や TimezoneInfo などが正しくタイムゾーン情報を扱えるようにする際、OS のレジストリを見てもよいのか? という議論が当時ありました。(本来 System.* 下のライブラリは Windows OS 依存であってはならないため) しかし一方で、タイムゾーンや夏時間情報は割と頻繁にアップデートされるため、それを .NET Framework のパッチとして提供するのも非現実的である、という判断から、OS のレジストリを見る、という設計にしたらしいです。

    いやー、ホントにタイムゾーン考えずに作られたシステムを、今更タイムゾーン対応にするのってさすがにぞっとしますですよ、ええ;。後ろ向き対応なので、うっかりするとお金払わないとかサービスで対応しろとかいうお客様も割と簡単に出てきそうなので、いやもう IT 業界全員で断固として反対する必要があるかと....;

Skip to main content