SET TIME ZONE
SET TIME ZONE キーワードを使用すると、ロケールの世界協定時刻(Coordinated Universal Time:UTC)を基に現在時刻のオフセットを指定することができ、これによって、データベース エンジンが配置されているオペレーティング システムのタイム ゾーンの設定を無効にできます。
SET TIME ZONE ステートメントの効果は現在のデータベース セッションの間中、または別の SET TIME ZONE ステートメントが実行されるまで適用されます。
注意: お使いのオペレーティング システムのタイム ゾーンの設定を特に無効にする必要がなければ、常にデフォルトの動作を使用してください。DataExchange レプリケーションを使用している場合、またはアプリケーションに各レコードが挿入される時刻順序との依存関係がある場合は、SET TIME ZONE を使ってタイム ゾーンのオフセットを変更することはお勧めしません。
構文
SET TIME ZONE <ディスプレースメント | LOCAL>
ディスプレースメント ::= <+|->hh:mm
hh の有効な範囲は 00 - 12 です。
mm の有効な範囲は 00 - 59 です。
プラス記号(+)またはマイナス記号(-)は、ディスプレースメント値の一部として必要です。
備考
デフォルトの動作 - SET TIME ZONE LOCAL がデフォルトの動作で、これは SET TIME ZONE コマンドをまったく使用しないのと同じです。デフォルトの動作の場合、データベース エンジンは実行しているオペレーティング システムに基づいてそのタイム ゾーンを設定します。たとえば、SELECT
CURTIME ( ) では現在の現地時刻を返しますが、SELECT
CURRENT_TIME ( ) では、オペレーティング システムの地域のシステム時刻とタイム ゾーンの設定の両方に基づいて現在の世界協定時刻(UTC)を返します。
LOCAL キーワードを使用すると、ディスプレースメントを指定した後で、データベース セッションを終了および再オープンすることなく、デフォルトの動作に戻すことができます。
デフォルトの動作の場合、'1996-03-28' や '17:40:46' などの日付/時刻のリテラル値は現在の現地日付/時刻として解釈されます。また、挿入中には、
TIMESTAMP リテラル値は指定した現在の現地時刻として解釈されます。TIMESTAMP 値は常に UTC 時刻を使って調整されてから内部的に保存され、取得時に現地時刻に変換されます。
表 42 SET TIME ZONE を使用する日付/時刻関数 - デフォルト
タイム ゾーンが指定されていない場合、または TIME ZONE LOCAL が指定されている場合 |
CURDATE()、CURTIME()、NOW() | これらの関数はシステム時計に基づいて現在の現地時刻を返します。 |
CURRENT_DATE()、CURRENT_TIME()、CURRENT_TIMESTAMP() | これらの関数は、常にシステム時計とオペレーティング システムの地域の設定に基づいて現在の UTC 日付/時刻を返します。 |
間隔を指定した場合の動作 ‐ 有効なディスプレースメント値が指定されると、
NOW ( )、
CURTIME ( ) または
CURDATE ( ) 用に値を生成するときに、オペレーティング システムのタイム ゾーンのオフセットではなくその値を使用します。たとえば、ディスプレースメントに -02:00 を指定した場合、CURDATE() の現地時刻の値はオペレーティング システムから返される UTC 時刻に -02:00 が加算された値になります。
この動作の場合、日付と時刻のリテラルは、そのままの値で現地時刻として解釈されます。
TIMESTAMP リテラルでは、
ディスプレースメントを減算した場合に結果が UTC となるような時刻を指定しているものと解釈されます。夏時刻は
ディスプレースメントで明示的に設定するので、考慮しません。TIMESTAMP 値は常に UTC 時刻を使って内部的に保存されます。
表 43 SET TIME ZONE を使用する日付/時刻関数 - 指定
有効なディスプレースメント値が指定された場合 |
CURDATE()、CURTIME()、NOW() | これらの関数は、現在の UTC 日付/時刻値にディスプレースメントを加算して現在の現地日付/時刻値を返します。 |
CURRENT_DATE()、CURRENT_TIME()、CURRENT_TIMESTAMP() | これらの関数は、常にシステム時計とオペレーティング システムの地域の設定に基づいて現在の UTC 日付/時刻を返します。 |
指定した現地時刻値を UTC に変換するには、その現地時刻の値からタイム ゾーンのディスプレースメントを減算する必要があります。つまり次のようになります。
UTC 時刻 = 現地時刻 - タイム ゾーンのディスプレースメント
表 44 現地時刻から UTC への変換例
現地時刻 | ディスプレースメント | UTC |
10:10:15 オースチン、テキサス | US 中部標準時 -06:00 | 10:10:15-(-06:00)=16:10:15 UTC |
16:10:15 ロンドン | グリニッジ標準時 +00:00 | 16:10:15-(+00:00)=16:10:15 UTC |
22:10:15 ダッカ | +06:00 | 22:10:15-(+06:00)=16:10:15 UTC |
TIMESTAMP データ型に関する注記
TIMESTAMP データは常に UTC として保存され、リテラル タイムスタンプ値はディスクに保存されている値も含め、取得するときに常に現地時刻へ変換されるため、
NOW ( ) 値と
CURRENT_TIMESTAMP ( ) 値の動作は混乱を招く可能性があります。たとえば、次の表ではデータベース エンジンが U.S. 中部標準時に設定されているとします。
表 45 Timestamp データ型の例
ステートメント | 値 |
SELECT NOW() | 2001-10-01 12:05:000.123 が表示されます。 |
INSERT INTO t1 (c1) SELECT NOW() | 2001-10-01 18:05:000.1234567 がディスクに保存されます。 |
SELECT * from t1 | 2001-10-01 12:05:000.123 が表示されます。 |
SELECT CURRENT_TIMESTAMP() | 2001-10-01 18:05:000.123 が表示されます。 |
INSERT INTO t2 (c1) SELECT CURRENT_TIMESTAMP() | 2001-10-01 18:05:000.1234567 がディスクに保存されます。 |
SELECT * from t2 | 2001-10-01 12:05:000.123 が表示されます。 |
直接の SELECT
NOW ( ) で表示される値は、INSERT SELECT
NOW ( ) 構文によってディスクに保存される値とは異なることに注意することが重要です。また、SELECT
CURRENT_TIMESTAMP ( ) の表示値も、CURRENT_TIMESTAMP() の値を INSERT した後でそれを SELECT した場合(INSERT SELECT CURRENT_TIMESTAMP() 構文)に表示される値とは異なることに注意してください。これは、データ ファイルに保存したリテラル値を取得するときに値が調整されるからです。
例
次の例では、SET TIME ZONE ステートメントがまだ発行されておらず、データベース エンジンが起動しているコンピューターのシステム時計は January 9, 2002, 16:35:03 CST(U.S.)に設定されています。CURRENT_TIMESTAMP() およびその他の CURRENT_ 関数では、常にデータベース エンジンが起動しているコンピューターのシステム時計と地域の設定に基づく UTC 日付/時刻を返すことを思い出してください。
SELECT CURRENT_TIMESTAMP(), NOW(),
CURRENT_TIME(), CURTIME(),
CURRENT_DATE(), CURDATE()
結果:
2002-01-09 22:35:03.000 2002-01-09 16:35:03.000
22:35:03 16:35:03
01/09/2002 01/09/2002
CST は UTC の 6 時間前であることに注意してください。
SET TIME ZONE -10:00
これによって、上記の同じ SELECT ステートメントでは次の値を返します。
2002-01-09 22:35:03.000 2002-01-09 12:35:03.000
22:35:03 12:35:03
2002-01-09 2002-01-09
SET TIME ZONE ステートメントを発行後 NOW() の値は変わりましたが、CURRENT_TIMESTAMP() の値は変わらなかったことに注目してください。
============
次の例では、UTC 値として保存され取得時に現地時刻の値に変換される TIMESTAMP 値と、そのままの値で保存および取得される TIME または DATE 値との違いを示します。現在、システム時計は January 9, 2002, 16:35:03 CST(U.S.)を示しているものとします。また、SET TIME ZONE ステートメントはまだ発行されていないことを前提とします。
CREATE TABLE t1 (c1 TIMESTAMP, c2 TIMESTAMP, c3 TIME, c4 TIME, c5 DATE, c6 DATE)
INSERT INTO t1 SELECT CURRENT_TIMESTAMP(), NOW(), CURRENT_TIME(), CURTIME(),
CURRENT_DATE(), CURDATE()
SELECT * FROM t1
結果:
c1 c2
----------------------- -----------------------
2002-01-09 16:35:03.000 2002-01-09 16:35:03.000
c3 c4 c5 c6
-------- -------- ---------- ----------
22:35:03 16:35:03 01/09/2002 01/09/2002
NOW() と CURRENT_TIMESTAMP() は、SELECT NOW()、CURRENT_TIMESTAMP() で画面に表示される場合には異なる値になりますが、いったんリテラル値をディスクに保存すると、両方の値に UTC 時刻が格納されることに注意してください。取得時に、両方の値が現地時刻に変換されます。
タイム ゾーン間隔をゼロに設定すると、取得時に +00:00 によって調整されるので、ファイルに保存された実際のデータを見ることができます。
SET TIME ZONE +00:00
SELECT * FROM t1
結果:
c1 c2
----------------------- -----------------------
2002-01-09 22:35:03.000 2002-01-09 22:35:03.000
c3 c4 c5 c6
-------- -------- ---------- ----------
22:35:03 16:35:03 01/09/2002 01/09/2002
============
次の例では、現地日付が UTC 日付と異なる場合に予期される動作を示します(たとえば、UTC は午前 0 時を過ぎているが、現地時刻ではまだ午前 0 時前の場合。またはその逆の場合)。現在、システム時計は January 9, 2002, 16:35:03 CST(U.S.)を示しているものとします。
SET TIME ZONE +10:00
SELECT CURRENT_TIMESTAMP(), NOW(),
CURRENT_TIME(), CURTIME(),
CURRENT_DATE(), CURDATE()
結果:
2002-01-09 22:35:03.000 2002-01-10 08:35:03.000
22:35:03 08:35:03
01/09/2002 01/10/2002
INSERT INTO t1 SELECT CURRENT_TIMESTAMP(), NOW(), CURRENT_TIME(), CURTIME(),
CURRENT_DATE(), CURDATE()
SELECT * FROM t1
結果:
c1 c2
----------------------- -----------------------
2002-01-10 08:35:03.000 2002-01-10 08:35:03.000
c3 c4 c5 c6
-------- -------- ---------- ----------
22:59:55 08:59:55 01/09/2002 01/10/2002
ご覧のとおり、CURRENT_DATE() および CURRENT_TIME() で返される UTC 時刻と日付はリテラル値として保存されます。これらは TIMESTAMP 値ではないので、データベースから取得するときに調整が行われません。
関連項目