3.4. 日付データ型

PostgresはSQLの日にちと 時間型をすべてサポートしています。

Table 3-6. 日付データ型

型説明データベース上のバイト数最古値最新値精度
timestamp年月日時分秒8 バイト4713 BCAD 14650011マイクロセカンド/14桁
timestamp [ with time zone ]タイムゾーン付き年月日時分秒8 バイト1903 AD2037 AD1マイクロセカンド/14桁
interval日付/時刻の差12 バイト-178000000 年178000000 年1 マイクロセカンド
date日付のみ4 バイト4713 BC32767 AD1 日
time [ without time zone ]タイムゾーンなし時刻8 バイト00:00:00.0023:59:59.991 マイクロセカンド
time with time zoneタイムゾーン付き時刻12 バイト00:00:00.00+1223:59:59.99-121 マイクロセカンド

Note: Postgresの前のバージョンとの互換性を確実に保つために、 datetime型(timestampと同じ)とtimespan型 (intervalと同じ)も引き続き提供します。しかし、これらは 現在timestamp型とinterval型に移行しているので、 制限されています。abstime型とreltime型は 精度が低い型で、内部で使用されています。新しいアプリケーションには これらの型の使用は避け、また適当な時に古いものは削除して下さい。 これらの型は今後のリリースで削除される可能性があります。

3.4.1. 日付/時間入力

日付と時間はISO-8601や互換性のあるSQL、 伝来のPostgresなど多くのフォーマットで入力可能です。 日付の月と日にちの順序は決められたものがないので、どのように解釈されるべきなのかを 設定しなければなりません。SET DateStyle TO 'US'や SET DateStyle TO 'NonEuropean'コマンドは様々な "月のあとに日にち形式"を 設定し、またSET DateStyle TO 'European'コマンドは 様々な"日にちのあとに月形式"に設定します。ISO形式がデフォルトと なっていますが、コンパイル時、または実行中に変えることが可能です。

日時の正確な入力方法と使用可能なタイムゾーンについてはAppendix Aを ご覧下さい。

文字列のように、日付や時間はシングルクォーテーションで囲む必要があります。 詳細はSection 1.1.2.5をご覧下さい。 SQLには下記の構文が必要ですが、Postgresは もっと柔軟です。

type 'value'

3.4.1.1. 日付

date 型では下記の入力が可能です。

Table 3-7. 日付入力

例説明
January 8, 1999変更不可
1999-01-08ISO-8601のフォーマット。推奨。
1/8/1999US形式。ヨーロッパモードでは8月1日と認識されます。
8/1/1999ヨーロッパ形式。USモードでは8月1日と認識されます。
1/18/1999米国形式。このケースではどのモードでも1月18日と認識されます。
19990108ISO-8601の年、月、日付
990108ISO-8601の年、月、日付
1999.008年とその日までの累計
99008年とその日までの累計
January 8, 99 BC西暦紀元の99年前

Table 3-8. 月の短縮形式

月短縮形式
4月Apr
8月Aug
12月Dec
2月Feb
1月Jan
7月Jul
6月Jun
3月Mar
11月Nov
10月Oct
9月Sep, Sept

Note: 5月には略する必要性がないので、短縮形式がありません。

Table 3-9. 曜日の短縮形式

曜日短縮形式
日曜日Sun
月曜日Mon
火曜日Tue, Tues
水曜日Wed, Weds
木曜日Thu, Thur, Thurs
金曜日Fri
土曜日Sat

3.4.1.2. タイムゾーンなし時刻

SQL99では、この型はtimeとtime without time zoneの 両方を使用できます。

下記がtime型の入力として可能です。

Table 3-10. 時刻入力

例説明
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と同義です。

3.4.1.3. タイムゾーンつき時刻

この型はSQL92で定義されていますが、その定義は根本的な部分の欠陥があり、 この型をほとんど無益なものとしています。ほとんどの場合、date型、 time型、timestamp型との組み合わせをもって、 あらゆるアプリケーションで必要とされる日付/時刻の機能を提供できるはずです。

time with time zone型ではtime型で使用可能な入力方法は すべて使用でき、適切なタイムゾーンを付けます。

Table 3-11. タイムゾーンつき時刻入力

例説明
04:05:06.789-8ISO-8601
04:05:06-08:00ISO-8601
04:05-08:00ISO-8601
040506-08ISO-8601

タイムゾーンに関するほかの例はTable 3-12を ご覧下さい。

3.4.1.4. タイムスタンプ

timestamp型の有効な入力形式は日付と時刻の連結で行われ、 ADやBC、 タイムゾーンがオプションで付けられます。(下記参照)したがって、

1999-01-08 04:05:06 -8:00
      
は有効なtimestamp型の値で、ISO互換性があります。 また、広く使用されている
January 8 04:05:06 1999 PST
      
のフォーマットもサポートされています。

Table 3-12. タイムゾーン入力

タイムゾーン説明
PST太平洋標準時(PST)です。
-8:00PSTのオフセットを表すISO-8601です。
-800PSTのオフセットを表すISO-8601です。
-8PSTのオフセットを表すISO-8601です。

3.4.1.5. 日付/時刻の差

interval型は下記の構文で特定することが可能です。

  Quantity Unit [Quantity Unit...] [Direction]
@ Quantity Unit [Direction]
      
Quantity(時間量) は -1, 0, 1, 2, ...; Unit(単位) は second(秒), minute(分), hour(時), day(日), week(週), month(月), year(年), decade(10年間), century(1世紀), millennium(千年期)で、これら単位の短縮形や複数形です。 Direction(方向)はago、または空となります。

3.4.1.6. 特別な値

SQL互換性のあるCURRENT_DATE、 CURRENT_TIME、CURRENT_TIMESTAMP関数は 対応しているデータ型に日付/時間入力として使用することができます。

Postgresは便宜をはかるために特殊な定数が設けてあります。

Table 3-13. 特殊な 日付/時刻 定数

定数説明
currentトランザクションが行われた時点(下記参照)
epoch1970-01-01 00:00:00+00 Unix経時基準時刻
infinity有効な時間よりも大きい日付
-infinity有効な時間よりも小さい日付
invalid無効な入力
nowトランザクションが行われた時点(下記参照)
today本日
tomorrow明日
yesterday昨日
'now' は、値が挿入されたらその後変更されません。'current'は 呼び出される度に値は変わります。したがって、ほとんどのアプリケーションでは 'now' を使用することになると思われます。 (そのような場合は'now'と同等の CURRENT_TIMESTAMPを使用する場合が多いと思われます)

3.4.2. 日付/時刻 出力

出力形式フォーマットはSET DateStyleコマンドを使用して ISO-8601、SQL (Ingres)、伝来のPostgres、 Germanの いずれかに設定することができます。デフォルトはISOフォーマット となっています。

Table 3-14. 日付/時間 出力形式

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

date型とtime型の出力形式は言うまでもなく、 上記の例と一致している日付と時間の部分です。

SQL形式にはヨーロッパ式と非ヨーロッパ式(US)があり、 月の後に日にちなのか、それともその逆なのかの判断をします。(この設定がどのように値の 評価に影響するかの詳細は上記の日付/時間入力の説明をご覧下さい。)

Table 3-15. 日付順序の慣習

形式名説明例
European日/月/年17/12/1997 15:37:16.00 MET
US月/日/年12/17/1997 07:37:16.00 PST

interval型の出力形式は入力フォーマットと似ていますが、 週や世紀は年と日にちに変換されます。 ISOモードに於て、出力は下記のようになります。

[ Quantity Units [ ... ] ] [ Days ] Hours:Minutes [ ago ]

日付/時間データ型の出力形式撰択としていくつかの方法があります。

3.4.3. タイムゾーン

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

このような問題を解決するためには、タイムゾーンを使用する際、日付と時間の両方を 保持している日付/時間型を使用されることをお勧めします。 他のRDBMSの実装との互換性を持たせるためと、過去のアプリケーションのために PostgresでSQL92のTIME WITH TIME ZONEを サポートしていますが、利用はお勧めしません。 Postgresは日付、または時間だけを保持している あらゆる型の現地時間を推測します。また、タイムゾーンのサポートはOSの タイムゾーンの機能を使用しているので、サマータイムとその他の機能を 利用できます。

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

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

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

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

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

3.4.4. 内部

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

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