PostgreSQL は SQL の日付と時刻データ型のすべてをサポートしています。
Table 3-10. 日付/時刻データ型
型 | 説明 | 格納サイズ | 最遠の過去 | 最遠の未来 | 精度 |
---|---|---|---|---|---|
timestamp [ (p) ] without time zone | 日付と時刻両方 | 8 バイト | 4713 BC | AD 1465001 | 1 μ秒 / 14 桁 |
timestamp [ (p) ] [ with time zone ] | 日付と時刻両方 | 8 バイト | 4713 BC | AD 1465001 | 1 μ秒 / 14 桁 |
interval [ (p) ] | 日付/時刻の間隔 | 12 バイト | -178000000 years | 178000000 years | 1 μ秒 |
date | 日付のみ | 4 バイト | 4713 BC | 32767 AD | 1 日 |
time [ (p) ] [ without time zone ] | その日の時刻のみ | 8 バイト | 00:00:00.00 | 23:59:59.99 | 1 μ秒 |
time [ (p) ] with time zone | その日の時刻のみ | 12 バイト | 00:00:00.00+12 | 23:59:59.99-12 | 1 μ秒 |
time、timestamp、および interval は秒フィールドに保有されている小数点以下の桁数を指定するオプションの精度値である p を受け付けます。デフォルトでは、明示的な精度に帯する限界はありません。有効な精度の限界はシステムが使用している値の保存に用いる倍精度浮動小数点値で決まります(interval では秒単位、timestamp では 2000-01-01 以降秒単位です)。有効な p の範囲は timestamp で 0 から大まかに 6 までですが、interval ではもう少し広がる可能性があります。システムは 0 から 13 までの範囲の p を受け付けます。
時間帯および時間帯の取り決めは地球の幾何学的要素のみでなく政治的判断に影響されます。世界にまたがる時間帯は 1900 年代に標準化されたようですが勝手に変更する傾向が続いています。 PostgreSQL は時間帯による出力のサポートに使用しているオペレーティングシステムの機能を使いますが、これらのシステムは通常(伝統的な Unix システムの時間の範囲に一致する)1902 年から 2038 年までの情報しか所有していません。 時間帯付の timestamp と 時間帯付のtime はこの期間の範囲の時間帯情報を使用し、範囲外の日付/時刻を協定世界時間 (UTC) であると推定します。
7.0 より以前の PostgreSQL バージョンからのアップグレードを確実にするために datetime (timestamp と同じ)と timespan (interval と同じ)も認めています。現在これらのデータ型は timestamp とinterval への暗黙的な翻訳が制限されており、次の PostgreSQL のリリース(たぶん 7.3)では削除されるでしょう。
abstime と reltime は精度の低いデータ型で、内部で使用されています。新しいアプリケーションにはこれらの型の使用を避け、また適当な時に旧いものを更新してください。これらの型の一部またはすべてが今後のリリースでは削除される可能性があります。
日付と時刻の入力は、ISO 8601、SQL 互換、伝統的な PostgreSQL、その他を含むほとんどの適正と見なされるフォーマットを受け付けます。日付の入力における月と日の順序のようないずれとも解釈されるいくつかのフォーマットについてはそれらフィールドを好きな順序に指定できるようになっています。 SET DateStyle TO 'US' や SET DateStyle TO 'NonEuropean' コマンドは「月→日」順表記を指定し、 SET DateStyle TO 'European' コマンドは「日→月」順表記を設定します。 ISO 形式がデフォルトとなっていますが、コンパイル時、または実行時に変更できます。
PostgreSQL は日付/時刻の運用において SQL 標準が要求するものよりも柔軟に対応します。日付/時刻の入力における正確な構文解析ルールと、月および週、そして時間帯を含む使用可能なテキストフィールドに関しては Appendix A を参照してください。
テキスト文字列のように、日付や時刻リテラルは単一引用符で囲む必要があることを思い出して下さい。詳細は Section 1.1.2.5 を参照してください。 SQL9x では下記の構文が必要です。
type [ (p) ] 'value'
ここで、オプションである精度の指定 p は秒フィールドの小数点以下の桁数に一致した整数です。精度は time、timestamp、および interval に対して設定できます。
SQL99 によると、この型は time または 時間帯無しの time として指定できます。オプションの精度 p は 0 と 13 の範囲で、デフォルトは入力時刻リテラルの精度によります。
以下の time 入力が使えます。
この型は SQL92 で定義されていますが、その定義は役に立つのか疑がわれる性質のものです。ほとんどの場合、date、 time、timestamp without time zone、 timestamp with time zone との組み合わせで、あらゆるアプリケーションで必要とされる日付/時刻の機能を提供できるはずです。
オプションの精度 p は 0 から 13 までの範囲で、デフォルトは入力時刻リテラルの精度です。
time with time zone では以下のようにして公認の時間帯を付加し time に対して制度的にに妥当とされているものを含むすべての入力を受付けます。
Table 3-13. 時間帯付き時刻入力
例 | 説明 |
---|---|
04:05:06.789-8 | ISO 8601 |
04:05:06-08:00 | ISO 8601 |
04:05-08:00 | ISO 8601 |
040506-08 | ISO 8601 |
時間帯に関する例は Table 3-14 にもっとあります。
timestamp [ (p) ] without time zone データ型に対しての有効な入力はは日付と時刻の連結で、オプションの AD または BC、更にオプションの時間帯が続きます。(下記を参照。)従って、
1999-01-08 04:05:06
これは ISO 準拠の timestamp without time zone の有効な値でです。また、次の広く使われるフォーマットもサポートされています。
January 8 04:05:06 1999 PST
オプションの精度 p は 0 から 13 までの範囲で、デフォルトは入力 timestamp リテラルの精度です。
timestamp without time zone に対し入力で指定された明示的な時間帯は黙って無視されます。ということは、結果の日付/時刻の値は明示された入力値の日付/時刻フィールドから持ち込まれ、時間帯に調整されていません。
timestamp に対しての有効な入力はは日付と時刻の連結からなり、オプションの AD または BC、更にオプションの時間帯が続きます。(下記を参照。)従って、
1999-01-08 04:05:06 -8:00
これは ISO 準拠の timestamp の有効な値でです。また、次の広く使われるフォーマットもサポートされています。
January 8 04:05:06 1999 PST
オプションの精度 p は 0 から 13 までの範囲で、デフォルトは入力 timestamp リテラルの精度です。
interval の値は以下の構文で書くことができます。
Quantity Unit [Quantity Unit...] [Direction] @ Quantity Unit [Quantity Unit...] [Direction]
ここで、Quantity は(符号付き)時間量、Unit(単位) は 秒、分、時、 日、週、月、 年、10 年単位、世紀、 ミレニアム あるいはこれらの単位の簡略形または複数形です。 Direction(方向) は ago もしくは空です。アットマーク(@)はオプションで付けても付けなくても構いません。異なる単位における時間量は適切な符号付き計算値で明示的に付加されなければなりません。
日、時、分、および秒の時間量は明示的に単位を指名しないでも構いません。例えば、'1 12:59:10' は '1 日と 12 時間 59 分 10 秒' と同じです。
オプションの精度 p は 0 から 13 までの範囲で、デフォルトは入力リテラルの精度です。
SQL 互換の関数、CURRENT_DATE、 CURRENT_TIME、CURRENT_TIMESTAMPを対応するデータ型の日付または時間の入力に使用できます。
PostgreSQLでは、便宜をはかるために特殊な定数をサポートしています。
Table 3-15. 特殊な日付/時刻定数
定数 | 説明 |
---|---|
epoch | 1970-01-01 00:00:00+00 (Unix システムの基準時刻) |
infinity | 別の有効な時刻よりも後 |
-infinity | 別の有効な時刻より前 |
invalid | 無効な入力 |
now | 現トランザクションの時刻 |
today | 今日の始まり |
tomorrow | 明日の始まり |
yesterday | 昨日の始まり |
zulu, allballs, z | 00:00:00.00 GMT |
Note: PostgreSQL のバージョンが 7.2 になった時点で 「current」 は日付/時刻定数としてもはやサポートされていません。以前は、「current」 は特殊値として保存され、式またはデータ型の変換時にのみ 'now' に対して評価されました。
出力フォーマットは、SET DateStyle コマンドを使用して ISO 8601、SQL(Ingres)、伝統的な PostgreSQL、German のいずれかに設定することができます。デフォルトは ISO フォーマットとなっています。
Table 3-16. 日付/時刻出力形式
形式仕様 | 説明 | 例 |
---|---|---|
'ISO' | ISO-8601 標準 | 1997-12-17 07:37:16-08 |
'SQL' | 伝統的な形式 | 12/17/1997 07:37:16.00 PST |
'PostgreSQL' | 特有の形式 | Wed Dec 17 07:37:16 1997 PST |
'German' | 地域限定形式 | 17.12.1997 07:37:16.00 PST |
date と time の形式はいうまでもなく上記の例に基づいた日付と時刻の部分です。
SQL 形式にはヨーロッパとヨーロッパでない(米国)変形があって、月の後に日なのか、それともその逆なのかを決定します。(この設定が入力値の解釈にどう影響を与えるのかについては Section 3.5.1 も参考にしてください。)
interval の出力は 週あるいは 世紀が 年と日に変換される以外、入力フォーマットと同じように表現されます。ISO モードでの出力は以下のようになります。
[ Quantity Units [ ... ] ] [ Days ] Hours:Minutes [ ago ]
日付/時刻データ型の出力形式を決めるのにいくつかの方法があります。
postmaster を起動させる際にバックエンドが使用する環境変数 PGDATESTYLE で設定する。
セッション開始時にフロントエンド libpq が 使用する環境変数 PGDATESTYLE で設定する。
SQL の SET DATESTYLE コマンドを使用する。
PostgreSQL は汎用的に使用できるように SQL92 への互換性に対し最大限の努力をしています。しかし、SQL92 標準には、日付と時刻データ型および効能にたいして妙に混乱しています。2 つの明らかな問題点を以下に示します。
date にはそれに関連する時間帯がありませんが、 time にはあります。現実の世界において、時間帯はオフセットが夏時間への切り替えにより年間を通じてが変化することから、時刻と同様に日付もそれに結び付けられていないと意味がありません。
デフォルトの時間帯は GMT/UTC から整数定数オフセットとして指定されています。夏時間(DST) への切替えを跨いで日付/時刻演算を行う場合、夏時間を適用することはできません。
このような問題を解決するためには時間帯を使用する際、日付と時刻の両方を保持できる日付/時刻データ型を使うべきでしょう。(たとえ PostgreSQL が過去のアプリケーションのためにサポートしているから、さらに他の RDBMS の実装との互換性を持たせたいからとしても)SQL92 形式の 時間帯付き time の使用はお勧めしません。 PostgreSQL は、日付または時刻のみを保持しているいかなるデータ型に対しても使用している時間帯をそのまま使います。さらに、時間帯のサポートは使用しているオペレーティングシステムの時間帯機能を使用しているため、夏時間やその他の機能を処理できます。
PostgreSQL は(Unix 系システムの典型的な日付の限界の近辺である)1902 年から 2038 年までの間は、使用しているオペレーティングシステムが提供する時間帯を獲得します。この範囲以外のすべての日付は協定世界時間 (UTC:Universal Coordinated Time)が指定されたものと仮定され、そして使用されます。
すべての日付と時刻は伝統的にグリニッジ標準時(GMT)として知られているUTC で内部的に保存されます。時刻はクライアントフロントエンドに送られる前にデータベースサーバの地域時刻に変換されるため、サーバでの時間帯がデフォルトになります。
いくつかの方法で時間帯を操作できます。
TZ 環境変数でデフォルトの時間帯を postmaster の起動時にバックエンドが読み込むようにします。
クライアントによって PGTZ 環境変数が設定されている場合、接続確立時にバックエンドに対し SET TIME ZONE コマンドを libpq が送信します。
SQL コマンドの SET TIME ZONE によってセッションで用いる時間帯を設定します。
次は SQL92 の資格付与子の働きの例です。
timestamp AT TIME ZONE 'zone'
ここで、zone は(例えば 'PST' のような)テキストによる時間帯、または(INTERVAL '-08:00' のような)時間間隔で指定することができます。
Note: 無効な時間帯が指定された場合(ほとんどのシステムで)時間帯はGMT になります。
Note: 実行時オプションに AUSTRALIAN_TIMEZONES が設定された場合、 CST と EST は米国時間帯でなくオーストラリア時間帯を参照します。
PostgreSQL はすべての日付と時刻の計算にユリウス暦を使っています。これは、紀元前 4,713 年から未来までのすべての日付を、1 年は 365.2425 日であると仮定し正確な予測や計算をするという優れた特性を持っています。
19 世紀以前の日付規則はおもしろい読み物にはなりますが、日付/時刻ハンドラの正しいコーディングを保証するは整合性につき完璧ではありません。