日付/時刻型

Postgres は絶対クロックタイム と相対時間間隔という、2種類の基本的な日付と時刻 の計測方法を提供しています。 時間自体がそうであるように、どちらの方法も継続的で滑らかな 量を持っています。

Postgres では、 SQL92 の2つの基本的なユーザ志向の日付/時刻 型である datetime 型と timespan 型 を提供しており、さらに timestamp 型、 interval 型、date 型、 time 型もサポートしています。

将来リリースされるバージョンでは、 datetime 型 と timespan 型は、SQL92timestamp 型と interval 型と統合 される可能性が高いと思われます。 他の日付と時刻に関するデータ型も、ほとんど歴史的な理由だけ で、利用可能となっています。

Table 3-7. Postgres 日付/時刻型

日付/時刻型記憶領域推奨説明
abstime4 bytesオリジナルの日付と時刻限られた範囲
date4 bytesSQL92広範囲
datetime8 bytes最良の汎用日付と時刻広範囲、高精度
interval12 bytesSQL92timespan 型と同等
reltime4 bytesオリジナルの時間間隔限られた範囲、低精度
time4 bytesSQL92広範囲
timespan12 bytes最良の汎用時間間隔広範囲、高精度
timestamp4 bytesSQL92限られた範囲
timestamp 型は、datetime とは別に 実装されていますが入出力ルーチンを共有しています。

Table 3-8. Postgres 日付/時刻の範囲

日付/時刻型入力可能な最古の値入力可能な最新の値分解能
abstime1901-12-142038-01-191 秒
date4713 BC32767 AD1 日
datetime4713 BC1465001 AD1 マイクロ秒 から 14 桁まで
interval-178000000 年178000000 年1 マイクロ秒
reltime-68 年+68 年1 秒
time00:00:00.0023:59:59.991 マイクロ秒
timespan-178000000 年178000000 年1 マイクロ秒 (14 桁)
timestamp1901-12-142038-01-191 秒

SQL92 規約

Postgres は、汎用的に使用できる ようにと、SQL92 への準拠に対して最大限の 努力をしています。しかし、SQL92 標準には、一時凌ぎで混乱している日付/時刻型とその仕様が あります。2つの明白な問題点は:

実世界のタイムゾーンは、オフセットが夏時間の切り替えにより 一年を通じてが変化することから、時刻と同様に日付もそれに 結び付けられていないと意味がありません。

これらの問題に対処するため、 Postgres では日付と時刻の両方を 含む日付/時刻型に対してのみタイムゾーンを関連付けるように しており、日付または時刻の一方しか含まない型については ローカル時間と仮定しています。将来的には、タイムゾーンの サポートはオペレーティングシステムのタイムゾーン機能から 導き出すようにすれば夏時間による時刻の早まりや、その他の 振る舞いについてもうまく対応できるようになるでしょう。

将来のリリースでは、日付/時刻型の数を減らし、現在の datetime の実装は timestamp に なり、timespaninterval に、 そして (おそらく) abstime および reltimetimestampinterval に代わることでしょう。 ただ、SQL92 標準に有る他の分かり 難い日付/時刻型の定義を追求することはまずないでしょう。

日付と時刻のスタイル

出力フォーマットは、 ISO-8601、SQL (Ingres)、 従来からの Postgres、および German のうちのどれかに設定できます。

Table 3-9. Postgres の日付形式

出力形式名説明出力例
ISOISO-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

日付/時刻型の表示形式を変更するには、いくつかの方法があります:

Postgres v6.4 までの日付/時刻の デフォルト書式は、"非ヨーロッパ式の伝統的な Postgres 形式 です。 将来のリリースでは、デフォルトが日付仕様の曖昧さや Y2K 照合問題を緩和する ISO (ISO-8601互換) になると思われ ます。

カレンダ

Postgres はすべての日付と時刻 の計算に、ユリウス暦を使っています。 これは、紀元前4713年 から未来までの全ての日付を、1年は365.2425日であると仮定し 正確な予測や計算をするという優れた特性を持っています。

19世紀以前の日付規則は面白い読み物にはなりますが、 日付/時刻ハンドラを正しくコーディングするためには十分では ありません。

タイムゾーン

Postgres は (UNIX - ライクな システムの典型的な日付の限界である) 1902年から2038年までの 間は、オペレーティング・システム環境下のタイムゾーンサポート を受けますが、この範囲以外のすべての日付は、協定世界時間 (Universal Coordinated Time - (UTC)) が指定された物と仮定し 使用されます。

内部的にはすべての日付と時刻は、グリニッジ標準時 (GMT) としても知られてる UTC で保存されています。 時刻はクライアントフロントエンドに送られる前にデータベース サーバーの上でローカル時刻に変換されるため、サーバーでの タイムゾーンがデフォルトになります。

タイムゾーンの動作に影響を与える方法はいくつか有ります:

無効なタイムゾーンが指定された場合、ほとんどのシステムでは タイムゾーンは GMT になります。

日付/時刻の入力

一般的な日付や時刻の入力は、ISO 互換、 SQL 互換、伝統的な Postgres 形式 、およびその他 の日付や時刻を表す、実にいろいろなスタイルで行われますが、 それら日付/時刻の形式があいまいに解釈できる場合 (これは 多くの伝統的な日付仕様の形式では非常に高い確率ですが)、 Postgres はこの曖昧さを解決する ために形式設定を使います。

ほとんどの日付/時刻型は、データ入力コードを共有しています。 これらの型における入力では、実にさまざまなスタイルが存在しま す。数値型の日付表現においてもヨーロッパ型と US 型の慣習は異 なる場合があるので、データが入ってくる前に set datestyle コマンドを使うと適切な変換 が行われますが、これを設定しても、多様な入力形式は使用できる ことに注意してください。形式設定は、主に出力形式を決定し、 曖昧さを解決するために使われます。

currentinfinity-infinity という特別な値が提供されて います。 infinity は、他のすべての有効な時間以降を 表し、-infinity は、他のすべての有効な 時間以前を表します。current は、計算時に この値が現れると即座に、その計算時点の現在時刻に置き換えられ ます。

nowtodayyesterdaytomorrowepoch 等は特別な時刻を設定するのに使われ ます。now は、トランザクション実行時の 時刻を表し、今現在の時間を表す current とは違っています。epoch は、 Jan 1 00:00:00 1970 GMT のことです。

Table 3-11. Postgres 日付/時刻型の 特殊な定数

定数説明
currentトランザクション実行時の時間。 その後は変更されない。
epoch1970-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-08ISO-8601 形式
1/8/1999US形式; ヨーロッパモードだと8月1日と読まれる
8/1/1999ヨーロッパ形式; USモードだと8月1日と読まれる
1/18/1999US形式; どんなモードでも1月18日と読まれる
1999.008年号と日にち
19990108ISO-8601 形式、年月日
990108ISO-8601 形式、年月日
1999.008年号と日にち
99008年号と日にち
January 8, 99 BC紀元前 99 年 1 月 8 日

Table 3-13. Postgres における月名 の省略形

省略形
AprilApr
AugustAug
DecemberDec
FebruaryFeb
JanuaryJan
JulyJul
JuneJun
MarchMar
NovemberNov
OctoberOct
SeptemberSep, Sept

Note: 当たり前ですが、May (5月)は省略形を 持っていません。

Table 3-14. Postgres の曜日の省略形

曜日省略形
SundaySun
MondayMon
TuesdayTue, Tues
WednesdayWed, Weds
ThursdayThu, Thur, Thurs
FridayFri
SaturdaySat

Table 3-15. Postgres の時刻入力

入力例説明
04:05:06.789ISO-8601形式、全てのフィールドに入力有り
04:05:06ISO-8601形式
04:05ISO-8601形式
040506ISO-8601形式
04:05 AM04:05 と同じ; AM は入力に影響しない
04:05 PM16:05 と同じ; 時間の部分は12以下であること
z00:00:00 と同じ
zulu00:00:00 と同じ
allballs00:00:00 と同じ

Table 3-16. Postgres タイムゾーンの 入力

タイムゾーン説明
PST太平洋標準時間 (Pacific Standard Time)
-8:00ISO-8601形式、PST に対するオフセット値
-800ISO-8601形式、PST に対するオフセット値
-8ISO-8601形式、PST に対するオフセット値

Postgres が認識するタイムゾーンに ついての詳細は、 日付/時刻のサポート を参照下さい。

Note: コンパイラのオプションに USE_AUSTRALIAN_RULES をセットした 場合、EST というのは、UTC に対し +10:00 時間の時差を持った オーストラリア東部標準時 (Australia Eastern Std Time) のことです。

オーストラリアのタイムゾーンとそれらの別名は、 Postgres の全てのタイムゾーン参照 テーブル内にある物の中の1/4と成ります。

datetime 型

一般的な日付や時刻の入力は、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) で格納されます。入出力ルーチンは、時刻をサーバ のローカルタイムに変換します。

timespan

一般的な時間間隔の入力は、ISO 互換、SQL 互換、伝統的な Postgres 形式 ("相対時間:relative time" を参照)、およびその他の期間を表す 実にいろいろな形式で入力されます。出力フォーマットは、ISO 互換、 SQL 互換、およびデフォルト設定である、従来 からの Postgres 形式のいずれかです。 月や年は "定性的な" 時間間隔であり、他の "定性的な" 時間間隔である日や時とは別 々に格納されます。日付の計算においては、定性的な時間単位は、関連する日付/時刻 の内容を考慮して行われます。

期間は以下の書式により指定されます。

  時間量 単位 [時間量 単位...] [方向]
@ 時間量 単位 [方向]
ここで、
    時間量は ..., `-1', `0', `1', `2', ...
    単位は second, minute, 
    hour, day, 
    week, month, 
    year, decade, 
    century, millenium, 
    またはこれら単位の短縮形や複数形です。
    方向は ago です。

abstime 型

絶対時刻 (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 では、もはや時刻はグリニッジ標準時では読み書き されておらず、入出力ルーチンのデフォルトはローカルタイムゾーン を参照するようになっています。

datetime 型に許されている全ての特殊な値は、 "絶対時刻"にもそのまま使用できます。

reltime 型

reltime 型は、限られた範囲(前後 68 年間) と精度 ( 1 秒) を持つ時間間隔指定データ型です。 timespan 型の方が、より大きな範囲と高い精度を持って いるので好まれています。さらに重要なのは、 timespan 型は相対的な単位 (月や年) と量的な単位 (日、時など) を識別できますが、一方の reltime 型は、強制的に ひと月をちょうど30日と換算します。そのため、時間の計算が意図した 通り動かないことがあります。たとえば、reltime 型の 1 年を abstime 型の 今日 に加えても、1 年後の今日にはならず、今日から 360 日後になります。

reltime 型は、他の期間型と入出力ルーチンを共有しています。 詳細は timespan 型の章で詳しく説明されています。

timestamp

これは現在では、abstime データ型に非常に良く似た、限られた範囲 を持つ絶対時刻です。これは、汎用入力パーサを他の日付/時刻型と 共有しています。将来のリリースでは、これは datetime 型の機能を吸収し、 SQL92 準拠の方向に進みます。

timestamp 型は datetime 型と同じ書式を 使って設定されます。

interval

interval 型は SQL92 のデータ型 で、現在は timespan 型と言う Postgres のデータ型にマッピングされて います。

tinterval

時刻の範囲 (時間差) を以下のように指定します。

[ 'abstime' 'abstime' ]

ここで、
    abstime は絶対時刻フォーマットの時刻です。
current, infinity-infinity と言った abstime 型特有な値を 使うことが出来ます。