日付/時刻データ型

PostgreSQL 8.4.1文書
前のページ | 巻戻し | 第 8章データ型 | 早送り | 次のページ

# 8.5. 日付/時刻データ型

PostgreSQLでは、表8-9に示されているSQLの日付と時刻データ型の全てがサポートされています。 これらのデータ型で利用できる演算子については項9.9で説明します。

表 8-9. 日付/時刻データ型

型名 | 格納サイズ | 説明 | 最遠の過去 | 最遠の未来 | 精度
--- | --- | --- | --- | --- | ---
`timestamp [ (`p`) ] [ without time zone ]` | 8 バイト | 日付と時刻両方（時間帯なし） | 4713 BC | 294276 AD | 1μ秒、14桁
`timestamp [ (`p`) ] with time zone` | 8バイト | 日付と時刻両方、時間帯付き | 4713 BC | 294276 AD | 1μ秒、14桁
`date` | 4バイト | 日付（時刻なし） | 4713 BC | 5874897 AD | 1日
`time [ (`p`) ] [ without time zone ]` | 8バイト | 時刻（日付なし） | 00:00:00 | 24:00:00 | 1μ秒、14桁
`time [ (`p`) ] with time zone` | 12バイト | その日の時刻のみ、時間帯付き | 00:00:00+1459 | 24:00:00-1459 | 1μ秒、14桁
`interval [ `fields` ] [ (`p`) ]` | 12バイト | 時間間隔 | -178000000年 | 178000000年 | 1μ秒、14桁

> 注意: PostgreSQL 7.3より以前では、単なる`timestamp`は`timestamp with time zone`と同じでした。 これは、SQL互換性のために変更されました。

`time`、`timestamp`、および`interval`は秒フィールドに保有されている小数点以下の桁数を指定するオプションの精度値である`p`を受け付けます。 デフォルトでは、明示的な精度に対する限界はありません。 `p`の許容範囲は、`timestamp`型と`interval`型の場合は0から6です。

> 注意: `timestamp`の値が8バイト整数（現在のデフォルト）で格納されていれば、全ての値についてμ秒精度が有効です。`timestamp`の値が倍精度浮動小数点数（将来のサポートが保証されないコンパイル時のオプション）で格納されていると、有効な精度は6より小さいかもしれません。`timestamp`の値は2000-01-01深夜を基準にした経過秒数として格納されます。`timestamp`の値が浮動小数点数として格納されていれば、2000-01-01から数年の範囲でμ秒精度が得られますが、それより離脱すると精度は劣化します。浮動小数点datetimesを使用すると上で示した範囲より広い`timestamp`の値（4713 BCから5874897 ADまで）が認められます。

> 同じコンパイル時オプションは`time` および `interval` の値が浮動小数点数か、8ビット整数か、のいずれかによって格納されるかを決定します。浮動小数点の場合、大きな`interval`では間隔が増加する際に精度が落ちます。

`time`型で8バイト整数が使用された場合には、`p`は0から6までの範囲で使用可能です。 また、浮動小数点が使用される場合には0から10までが使用可能です。

`interval`データ型には追加のオプションがあり、以下の１つの語句を使用して格納されるフィールドの集合を制約します。

        YEAR
        MONTH
        DAY
        HOUR
        MINUTE
        SECOND
        YEAR TO MONTH
        DAY TO HOUR
        DAY TO MINUTE
        DAY TO SECOND
        HOUR TO MINUTE
        HOUR TO SECOND
        MINUTE TO SECOND

`fields` および `p`が共に指定されると、精度は秒のみに適用されるので、`fields`は`SECOND`を含まなければならないことに注意してください。

`time with time zone`は標準SQLで定義されていますが、その定義は、その有用性を疑問視することになりかねない特性を示しています。 ほとんどの場合、`date`、`time`、`timestamp without time zone`、`timestamp with time zone`の組み合わせで、全てのアプリケーションで要求される日付/時刻機能全てを提供しているはずです。

`abstime`と`reltime`は精度の低いデータ型で、内部で使用されます。 アプリケーションでこれらの型の使用を避けてください。これら内部型は今後のリリースで削除される可能性があります。

## 8.5.1. 日付/時刻の入力

日付と時刻の入力は、ISO 8601、SQL互換、伝統的なPOSTGRES、その他を含むほとんどの適正とみなされる書式を受け付けます。 日付の入力における日-月-年の順序のようないずれとも解釈されるいくつかの書式については、それらのフィールドを好きな順序に指定できるようになっています。 DateStyleパラメータを`MDY`に設定すれば、月日年という順で解釈され、`DMY`に設定すれば日月年という順で、`YMD`に設定すれば年月日という順で解釈されます。

PostgreSQLは日付/時刻の運用において標準SQLの要求よりも柔軟です。 日付/時刻の入力における正確な構文解析規則と、月および週、そして時間帯を含む使用可能なテキストフィールドに関しては付録Bを参照してください。

テキスト文字列のように、日付や時刻リテラルは単一引用符で囲む必要があることを思い出してください。 詳細は項4.1.2.7を参照してください。 SQLでは下記の構文が必要です。

    type [ (p) ] 'value'

ここで、`p`は秒フィールドの小数点以下の桁数を与えるオプションの精度の指定です。 精度は`time`、`timestamp`、および`interval`型に対して設定できます。 値の許容範囲は既に説明しています。 定数指定において精度指定がない場合は、デフォルトのリテラル値の精度になります。

### 8.5.1.1. 日付

表8-10は`date`型で入力可能なものの一部を示します。

表 8-10. 日付入力

例 | 説明
--- | ---
1999-01-08 | ISO 8601。全てのモードで1月8日になります（推奨書式）。
January 8, 1999 | 全ての`datestyle`入力モードにおいて曖昧さがありません。
1/8/1999 | `MDY`モードでは1月8日、`DMY`モードでは8月1日。
1/18/1999 | `MDY`モードでは1月18日、他のモードでは拒絶されます。
01/02/03 | `MDY`モードでは2003年1月2日、`DMY`モードでは2003年2月1日、`YMD`モードでは2001年2月3日。
1999-Jan-08 | 全てのモードで1月8日になります。
Jan-08-1999 | 全てのモードで1月8日になります。
08-Jan-1999 | 全てのモードで1月8日になります。
99-Jan-08 | `YMD`モードで1月8日、他のモードではエラー。
08-Jan-99 | 1月8日。ただし`YMD`モードではエラー。
Jan-08-99 | 1月8日。ただし`YMD`モードではエラー。
19990108 | ISO 8601。全てのモードで1月8日になります。
990108 | ISO 8601。全てのモードで1月8日になります。
1999.008 | 年とその日までの累計
J2451187 | ユリウス日
January 8, 99 BC | 西暦紀元前99年

### 8.5.1.2. 時刻

ある一日の時刻を表す型は`time [(`p`) ] without time zone`と`time [ (`p`) ] with time zone`です。 `time`単独では`time without time zone`と同じです。

これらの型への有効な入力は、時刻、その後にオプションで時間帯からなります （表8-11と表8-12を参照してください）。 `time without time zone`への入力に時間帯が指定された場合、時間帯は警告なく無視されます。 また、`America/New_York`など夏時間規則を含む時間帯名を使用していない限り、日付を指定することはできますが、これは無視されます。 この場合、標準か夏時間かどちらを適用するかを決定できるように、日付の指定が必要です。 適切な時間帯オフセットは`time with time zone`型の値に記録されています。

表 8-11. 時刻入力

例 | 説明
--- | ---
`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以下でなければなりません。
`04:05:06.789-8` | ISO 8601
`04:05:06-08:00` | ISO 8601
`04:05-08:00` | ISO 8601
`040506-08` | ISO 8601
`04:05:06 PST` | 省略形による時間帯の指定。
`2003-04-12 04:05:06 America/New_York` | 名前による時間帯の指定。

表 8-12. 時間帯入力

例 | 説明
--- | ---
`PST` | 省略形（米国太平洋標準時間）
`America/New_York` | 完全な時間帯名
`PST8PDT` |
`-8:00` | ISO 8601。PST用のオフセット
`-800` | ISO 8601。PST用のオフセット
`-8` | ISO 8601。PST用のオフセット
`zulu` | UTC用の軍事用略記
`z` | `zulu`の略記

時間帯の指定方法に関する詳細は 項8.5.3を参照してください。

### 8.5.1.3. タイムスタンプ

タイムスタンプ型への有効な入力は、日付と時刻をセットにしたもの、さらにその後にオプションで時間帯、その後にオプションで`AD`もしくは`BC`からなります （他に`AD`/`BC`を時間帯の前に付ける方法もありますが、これは推奨される順序ではありません）。 したがって、

    1999-01-08 04:05:06

と

    1999-01-08 04:05:06 -8:00

は有効な値で、ISO 8601に準拠しています。 また、広く使用されている

    January 8 04:05:06 1999 PST

という書式もサポートされます。

標準SQLでは、`timestamp without time zone`のリテラルと`timestamp with time zone`のリテラルを、"+"もしくは"-"記号と時刻の後の時間帯補正を付けて区別します。 そのため、標準に従うと、

    TIMESTAMP '2004-10-19 10:23:54'

は`timestamp without time zone`に、

    TIMESTAMP '2004-10-19 10:23:54+02'

は`timestamp with time zone`になります。 PostgreSQLは、その型が決まる前に文字列リテラルの内容を検証しません。 そのため上のように`timestamp without time zone`を扱います。 リテラルが確実に`timestamp with time zone`として扱われるようにするには、例えば、

    TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'

のように正しい明示的な型を指定してください。 `timestamp without time zone`と決定済みのリテラルでは、PostgreSQLは警告なく時間帯情報をすべて無視します。 つまり、結果の値は明示された入力値の日付/時刻フィールドから持ち込まれますが、時間帯の調整はなされません。

`timestamp with time zone`について内部に格納されている値は常にUTCです（協定世界時、歴史的にグリニッジ標準時GMTとして知られています）。 時間帯が明示的に指定された入力値は、その時間帯に適したオフセットを使用してUTCに変換されます。 入力文字列に時間帯が指定されていない場合は、システムのtimezoneパラメータに示されている値が時間帯とみなされ、`timezone`時間帯用のオフセットを使用してUTCに変換されます。

`timestamp with time zone`値が出力されると、この値はUTCから現行の`timezone`に変換され、その時間帯のローカル時間として表示されます。 他の時間帯での時間を表示するには、`timezone`を変更するか、あるいは`AT TIME ZONE`構文を使用します（項9.9.3 を参照）。

`timestamp without time zone`と`timestamp with time zone`間の変換では、通常`timestamp without time zone`値は`timezone`ローカル時間としてみなされる、または、指定されるものと想定されます。 `AT TIME ZONE`を使用する変換では、異なる時間帯を指定できます。

### 8.5.1.4. 時間間隔

`interval`の値は以下の構文で書くことができます。

    [@] quantity unit [quantity unit...] [direction]

ここで、`quantity`は（符号付き）時間量、`unit`（単位）は`microsecond`、`millisecond`、`second`（秒）、`minute`（分）、`hour`（時）、`day`（日）、`week`（週）、`month`（月）、`year`（年）、`decade`（10年単位）、`century`（100年単位）、`millennium`（1000年単位）あるいはこれらの単位の簡略形または複数形です。 `direction`（方向）は`ago`もしくは空です。 アットマーク（`@`）はオプションで、付けても付けなくても構いません。 異なる単位における時間量は適切に符号を考慮して暗黙的に足されます。

日、時、分、および秒の時間量は明示的に単位を指定しなくても構いません。 例えば、`'1 12:59:10'`は`'1日と12時間59分10秒'`と解釈されます。

秒以下のオプションの精度`p`は0から6までの範囲で、デフォルトは入力リテラルの精度です。

内部的には、`interval`の値は月数、日数および秒数として格納されています。ある月の日数は月によって変わりますし、夏時間が導入されていると1日が23時間であったり25時間であったりするからです。時間間隔は通常定数列、もしくは`timestamp`からの引き算で生成されますので、この様に保存すればほとんどの場合うまく行きます。`justify_days`と`justify_hours`関数で通常の範囲を越えた日にちと時刻を調整できます。

### 8.5.1.5. 特殊な値

PostgreSQLでは利便性のために、表8-13に示されているような特別な日付/時刻入力値をサポートしています。 `infinity`と`-infinity`の値は、特別にシステム内部で表現され、変更されずに表示されます。 他のものは、単に簡略化された表記で、読み込まれる際には通常の日付/時刻値に変換されます （特に`now`とその関連文字列は読み込まれるとすぐにその時点の値に変換されます）。 これらの値は全て、SQLコマンドで定数として使う場合は、単一引用符で括らなければなりません。

表 8-13. 特殊な日付/時刻定数

入力文字列 | 有効な型 | 説明
--- | --- | ---
`epoch` | `date`, `timestamp` | 1970-01-01 00:00:00+00（Unixシステム時間におけるゼロ）
`infinity` | `date`, `timestamp` | 他の全てのタイムスタンプより遅い
`-infinity` | `date`, `timestamp` | 他の全てのタイムスタンプより早い
`now` | `date`, `time`, `timestamp` | 現トランザクションの開始時刻
`today` | `date`, `timestamp` | 今日の始まり
`tomorrow` | `date`, `timestamp` | 明日の始まり
`yesterday` | `date`, `timestamp` | 昨日の始まり
`allballs` | `time` | 00:00:00.00 UTC

SQL互換の関数である、`CURRENT_DATE`、`CURRENT_TIME`、`CURRENT_TIMESTAMP`、`LOCALTIME`、`LOCALTIMESTAMP`も、対応するデータ型の日付または時間の値として使用できます。 後の4つでは、オプションとして秒以下の精度指定が可能です （項9.9.4 を参照してください）。 これらはSQL関数であり、データ入力文字列認識されないことに注意してください。

## 8.5.2. 日付/時刻出力

日付/時刻型の出力書式は、ISO 8601、SQL（Ingres）、伝統的なPOSTGRES（Unix date書式）、またはGermanの４つのいずれかに設定されます。 デフォルトはISO書式です。（標準SQLではISO 8601書式の使用が定められています。"SQL"出力書式名は歴史的災難です）。 表8-14に各出力書式の例を示します。 `date`と`time`の書式は、言うまでもなく示された例のそれぞれ日付と時刻の部分となります。

表 8-14. 日付/時刻出力形式

様式仕様 | 説明 | 例
--- | --- | ---
ISO | ISO 8601/標準SQL | 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とPOSTGRESでは、DMYフィールド順が指定された場合は月の前に日が現れます。 指定がなければ日の前に月が現れます （この設定が入力値の解釈にどう影響を与えるのかについては項8.5.1を参考にしてください）。 表8-15に例を示します。

表 8-15. 日付の順序の慣習

`datestyle`の設定 | 入力の順序 | 出力例
--- | --- | ---
`SQL, DMY` | `day`（日）/`month`（月）/`year`（年） | 17/12/1997 15:37:16.00 CET
`SQL, MDY` | `month`（月）/`day`（日）/`year`（年） | 12/17/1997 07:37:16.00 PST
`Postgres, DMY` | `day`（日）/`month`（月）/`year`（年） | Wed 17 Dec 07:37:16 1997 PST

ユーザは`SET DATESTYLE`コマンド、`postgresql.conf`構成ファイルのDateStyleパラメータ、そしてサーバかクライアントの`PGDATESTYLE`環境変数を使用して、日付/時刻の様式を選択することができます。 日付/時刻出力のより柔軟な書式設定方法として、書式設定関数`to_char`（項9.8を参照）を使用することもできます。

## 8.5.3. 時間帯

時間帯および時間帯の取り決めは地球の幾何学的要素のみでなく政治的判断に影響されます。 世界にまたがる時間帯は1900年代に標準化されたようですが、特に夏時間規則の点で、勝手に変更する傾向が続いています。 PostgreSQLは歴史的な時間帯ルールについての情報に、広く使われている`zoneinfo`時間帯データベースを使用します。なぜなら、将来の時間は、その前提としてある与えられた時間帯に対する最新の既知のルールが、将来長きに渡りそのまま遵守が継続されるというものです。

PostgreSQLは汎用的に使用できるように標準SQLへの互換性に対し最大限の努力をしています。 しかし、標準SQLには、日付と時刻のデータ型と機能に関する混乱が見受けられます。 2つの明らかな問題点を以下に示します。

- `date`型にはそれに関連する時間帯を持てませんが、`time`型にはあります。 現実の世界において、時間帯のオフセットが夏時間への切り替えにより年間を通じて変化することから、時刻と同様に日付もそれに結び付けられていないと意味がありません。

- デフォルトの時間帯はUTCからの整数定数オフセットとして指定されています。 したがってDST（夏時間）への切り替えをまたいで日付/時刻演算を行う場合、夏時間を適用することは不可能です。

このような問題を解決するためには、時間帯を使用する際に日付と時刻の両方を保持できる日付/時刻データ型を使用することを勧めます。 `time with time zone`型の使用はお勧めしません （もっともPostgreSQLでは、旧式のアプリケーションや、標準SQLとの互換性のために、`time with time zone`型の使用をサポートしています）。 PostgreSQLは、日付または時刻のみを保持するデータ型の全ては使用中の時間帯であると前提しています。

全ての時間帯付きの日付と時刻はUTCで内部的に保存されます。 これらはクライアントに表示される前にtimezone設定パラメータで指定された時間帯におけるローカル時間に変換されます。

PostgreSQLでは、3つの形式で時間帯を指定することができます。

- `America/New_York`などの完全な時間帯名称。 認識できる時間帯名称は`pg_timezone_names`ビューに列挙されています（項44.58を参照してください）。 PostgreSQLはこの目的のためによく使用されている`zoneinfo`時間帯データを使用します。 したがって、多くの他のソフトウェアでも同じ名前が認識されます。

- `PST`などの時間帯省略形。 こうした指定は、単に特定のUTCからのオフセットを定義します。 一方完全な時間帯名称では夏時間遷移規則群も組み込まれます。 認識可能な省略形は`pg_timezone_abbrevs`ビューに列挙されています（項44.57を参照してください）。 時間帯省略形に対してtimezone設定パラメータおよびlog_timezone設定パラメータを設定することはできませんが、日付時刻型の入力値や`AT TIME ZONE`演算子に省略形を使用することができます。

- 時間帯名やその省略形に加え、PostgreSQLは、`STD` `offset`や`STD` `offset` `DST`という形式のPOSIX様式の時間帯指定を受付けます。 ここで、`STD`は時間帯省略形、`offset`はUTCから西に数えた時間単位のオフセットです。 また、`DST`は省略可能で夏時間時間帯の省略形で、指定オフセットから1時間進むことを意味します。 たとえば、`EST5EDT`が認識済みの時間帯名でない場合でも、受付けられ、合衆国東海岸時間と同じものとして動作します。 夏時間時間帯名があると、`zoneinfo`時間帯データベースの`posixrules`項目で使用される夏時間変換規則と同じ規則に従って使用されるものと前提されます。 標準的なPostgreSQLインストレーションでは、`posixrules`は`US/Eastern`と同じです。 このためPOSIX書式の時間帯指定はUSA夏時間規則に従います。 必要に応じて`posixrules`ファイルを置き換えることで、この動作を調整することができます。

一言で言うと、これは省略形と正式名称間の差異です。省略形はUTCから固定したオフセットを表わすのに対して、ほとんどの省略なしの名称はローカルの夏時間規定を意味するので、UTCオフセットには２つの可能性があります。

時間帯省略系の正当性を検査しないため、POSIX書式時間帯機能ではおかしな入力を警告なく受け付けてしまう可能性があることに注意すべきです。 例えば、システムの動作はより独特なUTCの省略系を使用し続けた状態で、`SET TIMEZONE TO FOOBAR0`でも動作します。 他にも、POSIX時間帯名称では正のオフセットがグリニッジの西側で使用されるという問題には注意しなければなりません。 PostgreSQLは、他ではすべてISO-8601規約にしたがい、正の時間帯オフセットはグリニッジの東としています。

全ての場合において、時間帯名は大文字小文字の区別なく認識されます。 （これはPostgreSQLのバージョン8.2以前からの変更です。以前は全てではありませんが、ある文脈では大文字小文字が区別されました。）

省略なし、省略形のどちらもサーバ内に組み込まれるわけではありません。インストールディレクトリの、`.../share/timezone/` および `.../share/timezonesets/`の下に保存される構成ファイルから取得されます（項B.3を参照ください）。

timezoneは`postgresql.conf`ファイルや第18章で説明する他の標準的な方法で設定することができます。 以下に、いくつか特別な設定方法を示します。

- `postgresql.conf`内やサーバのコマンドラインオプションで`timezone`が指定されていない場合、デフォルトの時間帯として`TZ`環境変数の値を使用しようと試みます。 `TZ`が定義されていない場合や`TZ`がPostgreSQLで認識可能な時間帯名称でなかった場合、サーバは、`localtime()`Cライブラリ関数の動作を検査することでオペレーティングシステムのデフォルトの時間帯を決定しようと試みます。 このデフォルトの時間帯は、PostgreSQLが認識可能な時間帯の中から最も近いものが選択されます。 （こうした規則は、log_timezoneが指定されていない場合のデフォルト値の選択方法でも使われます。）

- `SET TIME ZONE` SQLコマンドはセッションの時間帯を設定します。 これはSQL仕様互換の文法により従っている`SET TIMEZONE TO`の別名です。

- `PGTZ`環境変数は、libpqクライアントが接続時にサーバに`SET TIME ZONE`コマンドを送信するために用いられます。

## 8.5.4. 時間間隔入力

`interval`値は以下の冗長な構文を使って記述されます。

    [@] quantity unit [quantity unit...] [direction]

ここで、`quantity`は（符号付き）時間量、`unit`（単位）は`microsecond`、`millisecond`、`second`（秒）、`minute`（分）、`hour`（時）、`day`（日）、`week`（週）、`month`（月）、`year`（年）、`decade`（10年単位）、`century`（100年単位）、`millennium`（1000年単位）あるいはこれらの単位の簡略形または複数形です。 `direction`（方向）は`ago`もしくは空です。 アットマーク（`@`）はオプションで、付けても付けなくても構いません。 異なる単位における時間量は適切に符号を考慮して暗黙的に足されます。 `ago`はすべてのフィールドを反転させます。 この構文はまた、IntervalStyleが`postgres_verbose`に設定されている場合に時間間隔の出力でも使用されます。

日、時、分、および秒の時間量は明示的に単位を指定しなくても構いません。 例えば、`'1 12:59:10'`は`'1 day 12 hours 59 min 10 sec'`（1日と12時間59分10秒）と解釈されます。 また年と月の組み合わせはダッシュを使って指定することができます。 例えば、`'200-10'`は`'200 years 10 months'`（200年と10か月）と解釈されます。 （実際これらの簡略形は標準SQLで許されたもののみです。 そして`IntervalStyle`が`sql_standard`に設定されている場合に出力でも使用されます。）

標準の4.4.3.2節の"指定文字付書式"または4.4.3.3節の"代替書式"のどちらかを使用して、時間間隔値はISO 8601時間間隔として書くこともできます。 指定文字付の書式は以下のようなものです。

    P quantity unit [ quantity unit ...] [ T [ quantity unit ...]]

文字列は`P`で始まらなければならず、また、一日における時間をもたらす`T`を含めることができます。 利用可能な単位の省略形を表8-16に示します。 単位は省略しても構いません。また任意の順番で指定できます。 しかし、1日より小さな単位は`T`の後に書かなければなりません。 特に`M`の意味は`T`の前にあるか後にあるかに依存します。

表 8-16. ISO 8601 interval unit abbreviations

省略形 | 意味
--- | ---
Y | 年
M | 月（日付部分における）
W | 週
D | 日
H | 時間
M | 分（時刻部分における）
S | 秒

別の書式を示します。

    P [ years-months-days ] [ T hours:minutes:seconds ]

上の代替書式では、文字列は`P`から始まらなければなりません。 そして、`T`は時間間隔の日付部分と時刻部分とを分割します。 値はISO 8601日付と同様の数字で指定されます。

`fields`指定を使って時間間隔定数を記述する場合、または、`fields`仕様で定義された時間間隔列に文字列を割り当てる場合、マークされていない時間量の解釈は`fields`に依存します。 例えば`INTERVAL '1' YEAR`は1年と解釈され、一方で`INTERVAL '1'`は1秒と解釈されます。 同時に、`fields`仕様によって許可される最下位フィールドの"右側の"フィールド値は警告なしに破棄されます。例えば、`INTERVAL '1 day 2:03:04' HOUR TO MINUTE`と書くことで、二番目のフィールドは削除されますが、日付フィールドは削除されません。

標準SQLに従うと、時間間隔値のフィールドはすべて同じ符号を持たなければなりません。 このため、先頭の負の符号はすべてのフィールドに適用されます。 例えば時間間隔リテラル`'-1 2:03:04'`の負の符号は、日付部分にも時、分、秒部分にも適用されます。 PostgreSQLではフィールドに異なる符号を持たせることができます。 また伝統的にテキスト形式表現における各フィールドは独立した符号を持つものとして扱われます。 このため、この例では時、分、秒部分は正であるとみなされます。 `IntervalStyle`が`sql_standard`に設定されている場合、先頭の符号はすべてのフィールドに適用されるものとみなされます（ただし他に符号がない場合のみです）。 さもなくば、伝統的なPostgreSQLの解釈が使用されます。 あいまいさを防ぐために、負のフィールドがある場合には個別に明示的な符号を付けることを勧めます。

内部的には、`interval`の値は月数、日数および秒数として格納されています。 ある月の日数は月によって変わりますし、夏時間が導入されていると1日が23時間であったり25時間であったりするからです。 月数と日数フィールドは整数ですが、秒数フィールドは小数を保管することができます。 時間間隔は通常定数列、もしくは`timestamp`からの引き算で生成されますので、このように保存すればほとんどの場合うまく行きます。 `justify_days`と`justify_hours`関数で通常の範囲を越えた日にちと時刻を調整できます。

冗長な入力書式、および、より簡略な書式の一部のフィールドでは、フィールド値は小数部分を持つことができます。 例えば`'1.5 week'`や`'01:02:03.45'`です。 こうした入力は格納の際適切な月数、日数、秒数に変換されます。 これが月または日数が小数になる結果となる場合、小数部分は1月は30日、1日は24時間という変換規則を使用して、より低い順のフィールドに加えられます。 例えば`'1.5 month'`は1月と15日となります。 秒だけが出力において小数を示すことになります。

表8-17は有効な`interval`入力のいくつかの例を示しています。

表 8-17. 時間間隔入力

例 | 説明
--- | ---
1-2 | SQL 標準書式。1年2ヶ月
3 4:05:06 | SQL 標準書式。3日4時間5分6秒
1 year 2 months 3 days 4 hours 5 minutes 6 seconds | 伝統的Postgres書式1年2月3日4時間5分6秒
P1Y2M3DT4H5M6S | ISO 8601 "指定文字付き書式"。意味は上と同じ
P0001-02-03T04:05:06 | ISO 8601 "代替書式"。意味は上と同じ

## 8.5.5. 時間間隔出力

時間間隔型の出力書式は、`SET intervalstyle`コマンドを使用して、`sql_standard`、`postgres`、`postgres_verbose`、または`iso_8601`の４つのうちの１つを設定できます。デフォルトは`postgres`書式です。表8-18はそれぞれの出力形式を示した例です。

`sql_standard`形式は、時間間隔値が標準制約（構成要素に正負が混在していない年数と月数のみ、または日数と時間のみ）を満足する場合、時間間隔リテラル文字列に対しSQL標準に準拠する出力を作成します。そうでなければ、出力は、正負混在した時間間隔のあいまいさを無くす明示的な符号が付加され、日数-時間数リテラル文字列を伴った標準年数-月数リテラル文字列のようになります。

`postgres`書式の出力は、DateStyleパラメータが`ISO`に設定されたとき、8.4以前のリリースと一致します。

`postgres_verbose`書式の出力は、DateStyleパラメータが`ISO`に設定されたとき、8.4以前のリリースと一致します。

`iso_8601`書式の出力はISO 8601 標準の4.4.3.2セクションに記述の"format with designators（指名付き書式）"に一致します。

表 8-18. 時間間隔出力形式の例

形式指定 | 年-付き時間間隔 | 日-時刻時間間隔 | 混在した時間間隔
--- | --- | --- | ---
`sql_standard` | 1-2 | 3 4:05:06 | -1-2 +3 -4:05:06
`postgres` | 1 year 2 mons | 3 days 04:05:06 | -1 year -2 mons +3 days -04:05:06
`postgres_verbose` | @ 1 year 2 mons | @ 3 days 4 hours 5 mins 6 secs | @ 1 year 2 mons -3 days 4 hours 5 mins 6 secs ago
`iso_8601` | P1Y2M | P3DT4H5M6S | P-1Y-2M3DT-4H-5M-6S

## 8.5.6. 内部

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

19世紀以前の日付規則はおもしろい読み物にはなりますが、日付/時刻ハンドラの正しいコーディングを保証することは整合性について完璧ではありません。

前のページ | ホーム | 次のページ
バイナリ列データ型 | 上に戻る | 論理値データ型