PostgreSQL 使用一个内部的启发式分析器用于所有的日期/时间支持。 日期和时间都是以字串形式输入的,然后用一个初步的判断分解为在该数域里可以有什么样的信息。 每个数域都被解释,并且要么是被赋予一个数字值,要么是忽略, 要么是被拒绝。分析器里包含内部的查询表,用于所有文本域,包括月份,星期几,和时区。
这份附录包含这些查询表的信息,以及描述了分析器用来对时间和日期解码的步骤。
日期/时间类型输入都是使用下列的过程进行解码的。
把输入字串分解为一个个记号,然后把每个记号分成字串,时间,时区,或者数字几类。
如果一个数字记号包含一个冒号(:),那么这是一个时间字串。包括随后所有的数据位和冒号。
如果这个数字记号包含一个划线(-),斜杠(/), 或者两个或多个点(.),那么它就是一个日期字串,可能有一个文本月份。
如果这个记号只是数字,那么它要么是一个单独的字段, 要么是一个 ISO 8601 连接的日期(比如,19990113 是 1999 年一月 13 日)或者是连接的时间(比如,141516 是 14:15:16)。
如果记号以一个加号(+)开头或者减号(-)开头, 那么它要么是一个时区,要么就是一个特殊的字段。
如果记号是一个文本字串,那么和可能的字串进行匹配。
做一次二分表查找,看看这个记号是特殊字串(比如,today), 日期(比如,Thursday),月份(比如,January), 还是一个无关痛痒的字(比如,at,on)。
为字段设置数值和位掩码。比如,为 today 设置年,月,日, 以及为 now 这样的还需要设置另外的时,分,秒。
如果没有找到,则做一次类似的二分表搜索,找与记号匹配的时区。
如果还没有找到,抛出一个错误。
记号是一个数字或者数字字段。
如果有八位或者六位数字,而且前面也没有读到其它日期字段, 那么就解释成一个"连接的日期"(比如, 19990118 或者 990118)。 这里的解析是 YYYYMMDD 或者 YYMMDD。
如果记号是三位数字,并且已经解码了一个年份,那么解释成年日。
如果已经读取了四和六位数字,并且已经读取了一个年份, 那么就解析成时间(HHMM 或者 HHMMSS)。
如果是三位或更多位并且还没有找到日期字段,则解析成一个年份 (这个解析强制剩余的日期字段的顺序为 yy-mm-dd)。
那么解析成某一天。 否则,日期字段的顺序被认为是尊循 DateStyle 设置: mm-dd-yy,dd-mm-yy,或者 yy-mm-dd。如果发现月份或者日期字段超出范围, 则抛出一个错误。
如果声明了 BC,则对年份取其负数并加一,用于内部保存。 (在格里高利历法里没有零年,所以数字上的 1 BC 是公元零年。)
如果没有声明 BC,并且年份字段有两个数据位的长度, 那么把年份调整为 4 位。如果该字段小于 70,那么加 2000;否则,加 1900。
提示: 格里高利年份 AD 1-99可以用前导零的方式使用4位数字 (也就是说,0099 是 AD 99)。 以前的 PostgreSQL 版本接受三位数字的年份和一位数字的年份, 但是从版本 7.0 开始,这个规则更严格了,以减少可能的混淆。