サマータイムとOracleのTIMESTAMP WITH TIME ZONE型

イトウです。本日(3/8)からトロントはサマータイムになりました。
「3月なのにサマーなんてだいぶ気が早いな」と思っていたら、なんと今日の気温は10℃、明日は12℃と暖かい日が続いています。カナダに住む人たちの夏に対する強い思いが春の陽気を呼び寄せたのかも。日本でも以前に東京オリンピックでサマータイム導入の話がありちょっと話題になりましたが、実際にサマータイムのある地域に暮らしてみて気づいたこともあります。

そもそもサマータイムの方が長い

カナダでは3月の第2日曜日3:00にサマータイムが始まり、11月の第1日曜日2:00に終わります。約8か月、実に1年の2/3はサマータイムということになります。トロントのタイムゾーンは東部標準時(Eastern Standard Time, EST)と東部夏時間(Eastern Daylight Time, EDT)の2つですが、「標準」のほうが遥かに短いというのが不思議。

すべての地域でサマータイムを導入しているのではない

国土の広いカナダでは元々6つのタイムゾーンがあります。そして一部の州や地域ではサマータイムを導入していません。例えば、サスカチュワン州は州全体で中部標準時(CST)を通年採用していたり、オンタリオ州やケベック州では州内でサマータイムを導入していない地域がある等、対応に違いがあります。国内で複数の標準時と更にサマータイムが入り混じっている状況は、日本人からすると訳が分かりませんね。。バンクーバーのあるブリティッシュ・コロンビア州では1年中サマータイムのタイムゾーンとする法案が州議会に提出されたというニュースも見かけました。もう「サマータイム」って何だろう。

一般の人は夜が長くなる

サマータイムにより時計の針が1時間早まります。夏のトロントでは日没が夜の8〜9時頃になるので、仕事が終わってからも外でゆっくりと過ごすことができます。多くのレストランでパティオが開き、街中がとても賑やかに。寒く長い冬を過ごすカナダでは、みんな大好きサマータイム。

日本と仕事をしている人は辛い?

しかし、喜んでばかりいられない事情もあります。トロントはサマータイムになっても日本のタイムゾーンは変わりません。弊社の場合、24時間のシステム運用保守を日本と分割していますが、交代のタイミングは変わらない為、トロント側は業務開始と終了が1時間ずつ遅くなります。仕事の後に買い物や飲みに行きたいと思っても、標準時と比べて1時間短くなる逆転現象が生まれてしまうのです。また、日本とのWEB会議でも、日本時間で朝9時開始の場合、トロント側は夜7時開始だったのが夜8時開始になります。1日の終わりが遅くなるのは辛いなというのが個人的な感想です。ただ、仕事のない日は1日が長くて嬉しいのは皆と一緒。

ところでOracleではどうなの?

大分前置きが長くなりました。日本で仕事をしている時にはサマータイムを意識した運用を経験することはほとんどありませんでしたが、Oracle Databaseではタイムゾーンを意識した時刻を格納する為にTIMESTAMP WITH TIMEZONE型があり、指定のタイムゾーンでサマータイムかどうかを自動で判別して時間を返してくれます。ちょっと気になったので、どういう動きになるのか遊んでみました。

サマータイムへ切り替わる時刻を表示してみる

今回はOracle Live SQLを使って、ブラウザから19cのデータベースで動作を確認しました。手元に環境がなくてもSQLを実行できるので便利です。

TO_TIMESTAMP_TZファンクションを使うと、指定した文字列をTIMESTAMP WITH TIME ZONEデータ型の値に変換できるので、今日の標準時からサマータイムへの切替わりの例で確認してみます。TIMESTAMP WITH TIMEZONE型ではUTCに対するオフセットかタイムゾーンリージョンを示すTZR書式、TZD書式を指定することで、その地域に合わせた時刻を扱うことができます。ここでは標準時とサマータイムの違いが分かりやすいTZRとTZDを使ったタイムゾーンの指定をしています。

実際の時刻では2020年3月8日午前1:59の次は一気に3:00になります(2:00〜2:59が飛ばされる)。EST(東部標準時)とEDT(東部夏時間)のそれぞれで、1:00、2:00、3:00を表示させようとしてみたところ、存在しない時刻はエラーになり表示できませんでした(当たり前ですが)。1パターンだけエラー番号が異なるのが不思議ですね。

 

サマータイムを意識した計算を試してみる

次にサマータイムを意識した計算ができるのかを確認してみようと思います。3/8 0:00から1時間ずつ時刻を足していき、標準時からサマータイムに切替わるのかを試してみます。

1時間足した時はEST 1:00でしたが、2時間足したらEDT 3:00という結果になり、期待通りの動作になりました。

まとめ

TIMESTAMP WITH TIMEZONE型を使うことでOracleがサマータイムの切替えに対応できることが分かりました。日本でも海外とのシステム連携が必要な場合には利用しているケースもあると思います。一方で、テーブルのデータ型だけではない考慮も必要になります。例えば、SYSDATEのようにサーバ時刻を返す動作もある為、サーバ側でもサマータイム対応するのかどうか気になります。また、DATE型に比べてTIMESTAMP WITH TIMEZONE型のほうがバイト数が大きくなる(7バイト→13バイト)為、元あるシステムからデータ移行が必要な際にはテーブル設計等で注意が必要になりそうです。アプリケーションや他システムとの連携を考えると話は更に複雑になります。「本当に日本でサマータイム導入が見送られてよかった」というのが今回の結論です。

【参考】
SQL言語リファレンス
TO_TIMESTAMP_TZ
https://docs.oracle.com/cd/F19136_01/sqlrf/TO_TIMESTAMP_TZ.html#GUID-3999303B-89CA-4AA3-9817-458F36ADC9DC

Databaseグローバリゼーション・サポート・ガイド
4.2.1.3 TIMESTAMP WITH TIME ZONEデータ型
https://docs.oracle.com/cd/F19136_01/nlspg/datetime-data-types-and-time-zone-support.html#GUID-5BC5D2C1-6506-49BE-8177-F743A46FDC09
4.12 夏時間のサポート
https://docs.oracle.com/cd/F19136_01/nlspg/datetime-data-types-and-time-zone-support.html#GUID-E5171DEF-74D7-482A-B4E9-1EE3403E18BC