PostgreSQL は、すべての日付/時刻入力のサポートにおいて、内蔵している発見的パーサを使用します。日付と時刻は文字列で入力され、そのフィールドにはどのような種類の情報が入るのかが事前にに決められている別個のフィールドに分割されます。それぞれのフィールドは解釈されたのち数値を割り当てられたり、無視されたりあるいははねられたりします。構文解析に際し月、曜日、および時間帯を含むテキストフィールドに対する内部参照テーブルがあります。
この付録ではこれらの参照テーブルの内容についての情報と構文解析で日付と時刻を解読する手順を説明します。
日付/時刻データ型はすべて共通の決まったルーチンで解読されます。
日付/時刻入力の解釈
入力文字列をトークンに分割し、そしてそれぞれのトークンを文字列、時刻、時間帯、または数値というように分類します。
数値トークンにコロン (:) が含まれている場合は、時刻文字列です。そこに続くすべての数字とコロンを含みます。
数値トークンにハイフン (-)、スラッシュ (/)、または 2 つ以上のドット (.) が含まれている場合は、テキストの月名がある日付文字列です。
トークンが数値だけの場合、それは単項、もしくは ISO 8601 の連結形式の日付 (例: 1999 年 1月 13 日 を示す 19990113)、あるいは時刻 (例: 14:15:16 を示す 141516) のいずれかです。
トークンがプラス記号 (+) あるいはマイナス記号 (-) で始まっている場合は、時間帯フィールドか特殊なフィールドです。
もしトークンがテキスト文字列の場合、可能性のある文字列と照合されます。
トークンについて参照テーブルをバイナリ検索し、(today のような) 特殊文字列か、(Thursday のような) 曜日か、(January のような) 月か、あるいは (at や on のような) ノイズかを判定します。
フィールドの値とフィールドのビットマスクを設定します。例えば、today に年、月、日を設定し、それに追加して now に時、分、秒を設定します。
探索できなかった場合は類似の時間帯に見合うトークンに対しバイナリ検索を参照テーブルに掛けます。
それでも探し出せなかった場合、エラーを返します。
トークンは数値あるいは数値フィールドです。
トークンが 4 桁以上で、それより前に他のどのような日付フィールドも読まれていない場合は、「連結された日付」 (例えば、19990118) として解釈されます。8 桁と 6 桁の場合は年、月、日と解釈され、7 桁と 5 桁の場合、年と日数と解釈されます。
もしトークンが 3 桁で年がすでに解読されていた場合は日数と解釈されます。
4 桁または 6 桁の場合で年がすでに読み込まれている時は時刻と解釈されます。
4 桁以上の場合は年と解釈されます。
ヨーロッパ日付形式で日のフィールドが読まれておらず、その値が 31 以下の場合は日と解釈されます。
月のフィールドが読まれておらず、値が 12 以下の場合は月と解釈されます。
日のフィールドが読み込まれておらず、値が 31 以下の場合は日と解釈されます。
2 桁 もしくは 4 桁以上の場合は年と解釈されます。
それ以外はエラーとなります。
もし BC が指定された場合は内部格納用に年を負の数にして 1 を加えます。(グレゴリオ暦にはゼロ年がないので、数値的には 1BC (紀元前1年) がゼロ年になります。)
BC が指定されず年フィールドの長さが 2 桁の場合年は 4 桁になるよう調整されます。そのフィールドが 70 未満の場合は 2000 が加えられますが、そのほかの場合には 1900 が加えられます。
Tip: (例えば、西暦 99 年を 0099 のように) グレゴリオ暦の西暦元年から 99 年までは、ゼロを前に付加して 4 桁入力することができます。以前のバージョンの PostgreSQL では 3 桁でも 1 桁でも入力が可能でしたが、7.0 時点で、あいまいさを減らすためルールが厳格になり、現在では利用できません。