Postgres は絶対クロックタイム と相対時間間隔という、2種類の基本的な日付と時刻 の計測方法を提供しています。 時間自体がそうであるように、どちらの方法も継続的で滑らかな 量を持っています。
Postgres では、 SQL92 の2つの基本的なユーザ志向の日付/時刻 型である datetime 型と timespan 型 を提供しており、さらに timestamp 型、 interval 型、date 型、 time 型もサポートしています。
将来リリースされるバージョンでは、 datetime 型 と timespan 型は、SQL92 の timestamp 型と interval 型と統合 される可能性が高いと思われます。 他の日付と時刻に関するデータ型も、ほとんど歴史的な理由だけ で、利用可能となっています。
Table 3-7. Postgres 日付/時刻型
日付/時刻型 | 記憶領域 | 推奨 | 説明 |
---|---|---|---|
abstime | 4 bytes | オリジナルの日付と時刻 | 限られた範囲 |
date | 4 bytes | SQL92 型 | 広範囲 |
datetime | 8 bytes | 最良の汎用日付と時刻 | 広範囲、高精度 |
interval | 12 bytes | SQL92 型 | timespan 型と同等 |
reltime | 4 bytes | オリジナルの時間間隔 | 限られた範囲、低精度 |
time | 4 bytes | SQL92 型 | 広範囲 |
timespan | 12 bytes | 最良の汎用時間間隔 | 広範囲、高精度 |
timestamp | 4 bytes | SQL92 型 | 限られた範囲 |
Table 3-8. Postgres 日付/時刻の範囲
日付/時刻型 | 入力可能な最古の値 | 入力可能な最新の値 | 分解能 |
---|---|---|---|
abstime | 1901-12-14 | 2038-01-19 | 1 秒 |
date | 4713 BC | 32767 AD | 1 日 |
datetime | 4713 BC | 1465001 AD | 1 マイクロ秒 から 14 桁まで |
interval | -178000000 年 | 178000000 年 | 1 マイクロ秒 |
reltime | -68 年 | +68 年 | 1 秒 |
time | 00:00:00.00 | 23:59:59.99 | 1 マイクロ秒 |
timespan | -178000000 年 | 178000000 年 | 1 マイクロ秒 (14 桁) |
timestamp | 1901-12-14 | 2038-01-19 | 1 秒 |
Postgres は、汎用的に使用できる ようにと、SQL92 への準拠に対して最大限の 努力をしています。しかし、SQL92 標準には、一時凌ぎで混乱している日付/時刻型とその仕様が あります。2つの明白な問題点は:
date 型には関連するタイムゾーンはありませんが、 time 型にはあります。
デフォルトのタイムゾーンは GMT/UTC 時刻から一定の整数を 足したり引いたりするする事で設定されます。
これらの問題に対処するため、 Postgres では日付と時刻の両方を 含む日付/時刻型に対してのみタイムゾーンを関連付けるように しており、日付または時刻の一方しか含まない型については ローカル時間と仮定しています。将来的には、タイムゾーンの サポートはオペレーティングシステムのタイムゾーン機能から 導き出すようにすれば夏時間による時刻の早まりや、その他の 振る舞いについてもうまく対応できるようになるでしょう。
将来のリリースでは、日付/時刻型の数を減らし、現在の datetime の実装は timestamp に なり、timespan は interval に、 そして (おそらく) abstime および reltime は timestamp と interval に代わることでしょう。 ただ、SQL92 標準に有る他の分かり 難い日付/時刻型の定義を追求することはまずないでしょう。
出力フォーマットは、 ISO-8601、SQL (Ingres)、 従来からの Postgres、および German のうちのどれかに設定できます。
Table 3-9. Postgres の日付形式
出力形式名 | 説明 | 出力例 |
---|---|---|
ISO | ISO-8601 標準 | 1997-12-17 07:37:16-08 |
SQL | 従来からの形式 | 12/17/1997 07:37:16.00 PST |
Postgres | オリジナル | Wed Dec 17 07:37:16 1997 PST |
German | 地域固有の形式 | 17.12.1997 07:37:16.00 PST |
SQL 形式には、European (ヨーロッパ式)と non-European (非ヨーロッパ式) (あるいは US :アメリカ式) があり、 それらは日と月の順序が入れ替わります。
Table 3-10. Postgres の日付順序
形式仕様 | 説明 | 表示例 |
---|---|---|
European | 地域の習慣 | 17/12/1997 15:37:16.00 MET |
NonEuropean | 地域の習慣 | 12/17/1997 07:37:16.00 PST |
US | 地域の習慣 | 12/17/1997 07:37:16.00 PST |
日付/時刻型の表示形式を変更するには、いくつかの方法があります:
環境変数 PGDATESTYLE をバックエンド postmaster の起動時に 使用する。
環境変数 PGDATESTYLE をフロントエンド libpq 起動時に使用する。
SQL の SET DATESTYLE コマンドを使用する。
Postgres v6.4 までの日付/時刻の デフォルト書式は、"非ヨーロッパ式の伝統的な Postgres 形式 です。 将来のリリースでは、デフォルトが日付仕様の曖昧さや Y2K 照合問題を緩和する ISO (ISO-8601互換) になると思われ ます。
Postgres はすべての日付と時刻 の計算に、ユリウス暦を使っています。 これは、紀元前4713年 から未来までの全ての日付を、1年は365.2425日であると仮定し 正確な予測や計算をするという優れた特性を持っています。
19世紀以前の日付規則は面白い読み物にはなりますが、 日付/時刻ハンドラを正しくコーディングするためには十分では ありません。
Postgres は (UNIX - ライクな システムの典型的な日付の限界である) 1902年から2038年までの 間は、オペレーティング・システム環境下のタイムゾーンサポート を受けますが、この範囲以外のすべての日付は、協定世界時間 (Universal Coordinated Time - (UTC)) が指定された物と仮定し 使用されます。
内部的にはすべての日付と時刻は、グリニッジ標準時 (GMT) としても知られてる UTC で保存されています。 時刻はクライアントフロントエンドに送られる前にデータベース サーバーの上でローカル時刻に変換されるため、サーバーでの タイムゾーンがデフォルトになります。
タイムゾーンの動作に影響を与える方法はいくつか有ります:
環境変数 TZ を postmaster 起動時に与え、タイムゾーンの デフォルトとする。
コネクション確立時に、環境変数 PGTZ をクライアント側から libpq を使用してバックエンドにタイムゾーンの情報を与える。
SQL の SET TIME ZONE コマンドでセッション中のタイムゾーンを設定する。
無効なタイムゾーンが指定された場合、ほとんどのシステムでは タイムゾーンは GMT になります。
一般的な日付や時刻の入力は、ISO 互換、 SQL 互換、伝統的な Postgres 形式 、およびその他 の日付や時刻を表す、実にいろいろなスタイルで行われますが、 それら日付/時刻の形式があいまいに解釈できる場合 (これは 多くの伝統的な日付仕様の形式では非常に高い確率ですが)、 Postgres はこの曖昧さを解決する ために形式設定を使います。
ほとんどの日付/時刻型は、データ入力コードを共有しています。 これらの型における入力では、実にさまざまなスタイルが存在しま す。数値型の日付表現においてもヨーロッパ型と US 型の慣習は異 なる場合があるので、データが入ってくる前に set datestyle コマンドを使うと適切な変換 が行われますが、これを設定しても、多様な入力形式は使用できる ことに注意してください。形式設定は、主に出力形式を決定し、 曖昧さを解決するために使われます。
current、infinity、 -infinity という特別な値が提供されて います。 infinity は、他のすべての有効な時間以降を 表し、-infinity は、他のすべての有効な 時間以前を表します。current は、計算時に この値が現れると即座に、その計算時点の現在時刻に置き換えられ ます。
now、 today、 yesterday、tomorrow、 epoch 等は特別な時刻を設定するのに使われ ます。now は、トランザクション実行時の 時刻を表し、今現在の時間を表す current とは違っています。epoch は、 Jan 1 00:00:00 1970 GMT のことです。
Table 3-11. Postgres 日付/時刻型の 特殊な定数
定数 | 説明 |
---|---|
current | トランザクション実行時の時間。 その後は変更されない。 |
epoch | 1970-01-01 00:00:00+00 (Unix システムクロックの開始時間) |
infinity | 他のすべての有効な時刻以降 |
-infinity | 他のすべての有効な時刻以前 |
invalid | 無効なエントリ |
now | 現在のトランザクション実行時の時間 |
today | 今日の午前 0 時 |
tomorrow | 明日の午前 0 時 |
yesterday | 昨日の午前 0 時 |
Table 3-12. Postgres の日付入力
入力例 | 説明 |
---|---|
January 8, 1999 | 月名を長い形式で入力 |
1999-01-08 | ISO-8601 形式 |
1/8/1999 | US形式; ヨーロッパモードだと8月1日と読まれる |
8/1/1999 | ヨーロッパ形式; USモードだと8月1日と読まれる |
1/18/1999 | US形式; どんなモードでも1月18日と読まれる |
1999.008 | 年号と日にち |
19990108 | ISO-8601 形式、年月日 |
990108 | ISO-8601 形式、年月日 |
1999.008 | 年号と日にち |
99008 | 年号と日にち |
January 8, 99 BC | 紀元前 99 年 1 月 8 日 |
Table 3-13. Postgres における月名 の省略形
月 | 省略形 |
---|---|
April | Apr |
August | Aug |
December | Dec |
February | Feb |
January | Jan |
July | Jul |
June | Jun |
March | Mar |
November | Nov |
October | Oct |
September | Sep, Sept |
Note: 当たり前ですが、May (5月)は省略形を 持っていません。
Table 3-14. Postgres の曜日の省略形
曜日 | 省略形 |
---|---|
Sunday | Sun |
Monday | Mon |
Tuesday | Tue, Tues |
Wednesday | Wed, Weds |
Thursday | Thu, Thur, Thurs |
Friday | Fri |
Saturday | Sat |
Table 3-15. Postgres の時刻入力
入力例 | 説明 |
---|---|
04:05:06.789 | ISO-8601形式、全てのフィールドに入力有り |
04:05:06 | ISO-8601形式 |
04:05 | ISO-8601形式 |
040506 | ISO-8601形式 |
04:05 AM | 04:05 と同じ; AM は入力に影響しない |
04:05 PM | 16:05 と同じ; 時間の部分は12以下であること |
z | 00:00:00 と同じ |
zulu | 00:00:00 と同じ |
allballs | 00:00:00 と同じ |
Table 3-16. Postgres タイムゾーンの 入力
タイムゾーン | 説明 |
---|---|
PST | 太平洋標準時間 (Pacific Standard Time) |
-8:00 | ISO-8601形式、PST に対するオフセット値 |
-800 | ISO-8601形式、PST に対するオフセット値 |
-8 | ISO-8601形式、PST に対するオフセット値 |
Postgres が認識するタイムゾーンに ついての詳細は、 日付/時刻のサポート を参照下さい。
Note: コンパイラのオプションに USE_AUSTRALIAN_RULES をセットした 場合、EST というのは、UTC に対し +10:00 時間の時差を持った オーストラリア東部標準時 (Australia Eastern Std Time) のことです。
オーストラリアのタイムゾーンとそれらの別名は、 Postgres の全てのタイムゾーン参照 テーブル内にある物の中の1/4と成ります。
一般的な日付や時刻の入力は、ISO 互換、SQL 互換、伝統的な Postgres 形式 ("絶対時刻 : absolute time" を参照)、およびその他の日付や時刻を 表す、実にいろいろな形式で行われます。出力形式は、ISO 互換、 SQL 互換、およびデフォルト設定である、 Postgres v6.0 と互換性のある伝統的 Postgres 形式のいずれかです。
datetime 型は以下の書式を使って指定されます:
年-月-日 [ 時 : 分 : 秒 ] [AD,BC] [ タイムゾーン ] 年月日 [ 時 : 分 : 秒 ] [AD,BC] [ タイムゾーン ] 月 日 [ 時 : 分 : 秒 ] 年 [AD,BC] [ タイムゾーン ] ここで、 年は 4013 BC から巨大な数まで 月は Jan, Feb, ..., Dec あるいは 1, 2, ..., 12 日は 1, 2, ..., 31 時は 00, 02, ..., 23 分は 00, 01, ..., 59 秒は 00, 01, ..., 59 (60 はうるう秒) タイムゾーンは 3 文字、または GMT に対する ISO 式のオフセット
有効な日付は Nov 13 00:00:00 4013 BC GMT からほとんど無限の未来 です。 タイムゾーンは 3 文字 (例えば "GMT" または "PST") で表記するか、 あるいは GMT に対する ISO 互換のオフセット値 (例えば、太平洋 標準時:PSTでは "-08" または "-08:00") です。日付は内部的にはグリニッジ標準時 (GMT) で格納されます。入出力ルーチンは、時刻をサーバ のローカルタイムに変換します。
一般的な時間間隔の入力は、ISO 互換、SQL 互換、伝統的な Postgres 形式 ("相対時間:relative time" を参照)、およびその他の期間を表す 実にいろいろな形式で入力されます。出力フォーマットは、ISO 互換、 SQL 互換、およびデフォルト設定である、従来 からの Postgres 形式のいずれかです。 月や年は "定性的な" 時間間隔であり、他の "定性的な" 時間間隔である日や時とは別 々に格納されます。日付の計算においては、定性的な時間単位は、関連する日付/時刻 の内容を考慮して行われます。
期間は以下の書式により指定されます。
時間量 単位 [時間量 単位...] [方向] @ 時間量 単位 [方向] ここで、 時間量は ..., `-1', `0', `1', `2', ... 単位は second, minute, hour, day, week, month, year, decade, century, millenium, またはこれら単位の短縮形や複数形です。 方向は ago です。
絶対時刻 (abstime 型) は、限られた範囲 (前後68年間)と精度( 1 秒)をもつ日付データ型です。 より大きなデータ範囲と高い精度を持つ、 datetime 型の方が好まれています。
絶対時刻は以下の書式で指定します:
月 日 [ 時 : 分 : 秒 ] 年 [ タイムゾーン ] ここで、 月は Jan, Feb, ..., Dec or 1, 2, ..., 12 日は 1, 2, ..., 31 時は 01, 02, ..., 24 分は 00, 01, ..., 59 秒は 00, 01, ..., 59 (60 はうるう秒) 年は 1901, 1902, ..., 2038
有効な日付は Dec 13 20:45:53 1901 GMT から Jan 19 03:14:04 2038 GMT までです。
歴史的メモ: Version 3.0 では、もはや時刻はグリニッジ標準時では読み書き されておらず、入出力ルーチンのデフォルトはローカルタイムゾーン を参照するようになっています。
reltime 型は、限られた範囲(前後 68 年間) と精度 ( 1 秒) を持つ時間間隔指定データ型です。 timespan 型の方が、より大きな範囲と高い精度を持って いるので好まれています。さらに重要なのは、 timespan 型は相対的な単位 (月や年) と量的な単位 (日、時など) を識別できますが、一方の reltime 型は、強制的に ひと月をちょうど30日と換算します。そのため、時間の計算が意図した 通り動かないことがあります。たとえば、reltime 型の 1 年を abstime 型の 今日 に加えても、1 年後の今日にはならず、今日から 360 日後になります。
reltime 型は、他の期間型と入出力ルーチンを共有しています。 詳細は timespan 型の章で詳しく説明されています。
これは現在では、abstime データ型に非常に良く似た、限られた範囲 を持つ絶対時刻です。これは、汎用入力パーサを他の日付/時刻型と 共有しています。将来のリリースでは、これは datetime 型の機能を吸収し、 SQL92 準拠の方向に進みます。
timestamp 型は datetime 型と同じ書式を 使って設定されます。
interval 型は SQL92 のデータ型 で、現在は timespan 型と言う Postgres のデータ型にマッピングされて います。
時刻の範囲 (時間差) を以下のように指定します。
[ 'abstime' 'abstime' ] ここで、 abstime は絶対時刻フォーマットの時刻です。current, infinity、 -infinity と言った abstime 型特有な値を 使うことが出来ます。