?
? ????? PHP ??? ???? ??? ?? ??
Table 8-9顯示了PostgreSQL支持的SQL中所有日期和時(shí)間類(lèi)型。 這些數(shù)據(jù)類(lèi)型上可以進(jìn)行的操作在Section 9.9中描述。
Table 8-9. 日期/時(shí)間類(lèi)型
名字 | 存儲(chǔ)空間 | 描述 | 最低值 | 最高值 | 分辨率 |
---|---|---|---|---|---|
timestamp [ (p) ] [ without time zone ] | 8字節(jié) | 日期和時(shí)間(無(wú)時(shí)區(qū)) | 4713 BC | 294276 AD | 1毫秒/14位 |
timestamp [ (p) ] with time zone | 8字節(jié) | 日期和時(shí)間,帶時(shí)區(qū) | 4713 BC | 294276 AD | 1毫秒/14位 |
date | 4字節(jié) | 只用于日期 | 4713 BC | 5874897 AD | 1天 |
time [ (p) ] [ without time zone ] | 8字節(jié) | 只用于時(shí)間 | 00:00:00 | 24:00:00 | 1毫秒/14位 |
time [ (p) ] with time zone | 12字節(jié) | 只用于一日內(nèi)時(shí)間,帶時(shí)區(qū) | 00:00:00+1459 | 24:00:00-1459 | 1毫秒/14位 |
interval [ fields ] [ (p) ] | 12字節(jié) | 時(shí)間間隔 | -178000000年 | 178000000年 | 1毫秒/14位 |
Note: SQL標(biāo)準(zhǔn)要求僅僅將timestamp類(lèi)型 等于timestamp without time zone類(lèi)型,(7.3之前的版本將其看做timestamp with time zone)
time,timestamp和interval 接受一個(gè)可選的精度值p 以指明秒域中小數(shù)部分的位數(shù)。沒(méi)有明確的缺省精度, p的范圍對(duì)timestamp 和interval類(lèi)型是從0到大約6。
Note: 如果timestamp數(shù)值是以雙精度浮點(diǎn)數(shù)(目前的缺省)的方式存儲(chǔ)的, 微秒的精度是可以通過(guò)全方位的價(jià)值觀(guān)。當(dāng)timestamp值存儲(chǔ)為雙精度浮點(diǎn)數(shù)(1過(guò)時(shí)的編譯時(shí)間選項(xiàng)),那么有效精度會(huì)小于6。 timestamp值是以2000-01-01午夜之前或之后的秒數(shù)存儲(chǔ)的, 而微秒的精度是為那些在2000-01-01前后幾年的日期實(shí)現(xiàn)的,對(duì)于那些遠(yuǎn)一些的日子,精度會(huì)下降。 但當(dāng)timestamp值是使用浮點(diǎn)實(shí)現(xiàn)數(shù)字,日期內(nèi)取得幾微秒精度。 請(qǐng)注意,在以浮點(diǎn)數(shù)存儲(chǔ)的時(shí)候,隨著時(shí)間間隔的增加,timestamp數(shù)值的精度會(huì)降低。 如上圖所示:從公元前4713年至5874897 AD。
相同的編譯時(shí)間選項(xiàng)也決定是否time和interval值存儲(chǔ)為 浮點(diǎn)數(shù)或8字節(jié)的整數(shù)。在浮點(diǎn)運(yùn)算的情況下,大interval值降低 精密的間隔增加的大小。
對(duì)于time類(lèi)型,如果使用了八字節(jié)的整數(shù)存儲(chǔ), 那么p允許的范圍是從0到6, 如果使用的是浮點(diǎn)數(shù)存儲(chǔ),那么這個(gè)范圍是0到10。
interval類(lèi)型有一個(gè)額外的選項(xiàng),用于通過(guò)寫(xiě)這些詞組之一,限制存儲(chǔ)領(lǐng)域;
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
需要注意的是,如果同時(shí)聲明了fields和p, fields必須包括SECOND,因?yàn)榫戎贿m用于秒。
time with time zone類(lèi)型是SQL標(biāo)準(zhǔn)定義的, 但是完整定義的有些方面會(huì)導(dǎo)致有問(wèn)題的用法。 在大多數(shù)情況下,date,time,timestamp without time zone和timestamp with time zone的組合就應(yīng)該 能提供一切應(yīng)用需要的日期/時(shí)間的完整功能。
abstime和reltime類(lèi)型是低分辨率類(lèi)型, 它們被用于系統(tǒng)內(nèi)部。我們反對(duì)你使用這些類(lèi)型, 因?yàn)檫@些舊類(lèi)型的部分或全部可能會(huì)在未來(lái)的版本里消失。
日期和時(shí)間的輸入幾乎可以是任何合理的格式, 包括 ISO-8601 格式、SQL-兼容格式、傳統(tǒng)POSTGRES格式、其它的形式。 對(duì)于一些格式,日期輸入里的月和日可能會(huì)讓人迷惑, 因此系統(tǒng)支持自定義這些字段的順序。 把DateStyle參數(shù)設(shè)置為MDY就按照"月-日-年"解析, 設(shè)置為DMY就按照"日-月-年"解析,設(shè)置為YMD就按照"年-月-日"解析。
PostgreSQL在處理日期/時(shí)間輸入上 比SQL標(biāo)準(zhǔn)要求的更靈活。 參閱Appendix B獲取關(guān)于日期/時(shí)間輸入的 準(zhǔn)確分析規(guī)則和可識(shí)別文本字段,包括月份、星期幾、時(shí)區(qū)。
請(qǐng)記住任何日期或者時(shí)間的文本輸入需要由單引號(hào)包圍, 就像一個(gè)文本字符串一樣。參考Section 4.1.2.7 獲取更多信息。 SQL要求使用下面的語(yǔ)法:
type [ (p) ] 'value'
可選精度聲明中的p是一個(gè)整數(shù), 表示在秒域中小數(shù)部分的位數(shù),我們可以對(duì) time,timestamp,和interval類(lèi)型聲明精度。 允許的精度在上面已經(jīng)說(shuō)明。如果在常量聲明中沒(méi)有聲明精度,缺省是文本值的精度。
Table 8-10顯示了date類(lèi)型可能的輸入方式。
Table 8-10. 日期輸入
例子 | 描述 |
---|---|
1999-01-08 | ISO 8601格式(建議格式),任何方式下都是1999年1月8號(hào) |
January 8, 1999 | 在任何datestyle輸入模式下都無(wú)歧義 |
1/8/1999 | 在MDY下是一月八號(hào);在DMY模式下是八月一日 |
1/18/1999 | MDY 模式下是一月十八日,其它模式下被拒絕 |
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日,否則錯(cuò)誤 |
08-Jan-99 | 一月八日,除了在YMD模式下是錯(cuò)誤的之外 |
Jan-08-99 | 一月八日,除了在YMD模式下是錯(cuò)誤的之外 |
19990108 | ISO 8601;任何模式下都是1999年1月8日 |
990108 | ISO 8601;任何模式下都是1999年1月8日 |
1999.008 | 年和年里的第幾天 |
J2451187 | 儒略日 |
January 8, 99 BC | 公元前99年 |
當(dāng)日時(shí)間類(lèi)型是time [ (p) ] without time zone和 time [ (p) ] with time zone。 只寫(xiě)time等效于time without time zone。
這些類(lèi)型的有效輸入由當(dāng)日時(shí)間后面跟著可選的時(shí)區(qū)組成( 參閱Table 8-11和Table 8-12)。 如果在time without time zone類(lèi)型的輸入中聲明了時(shí)區(qū), 那么它會(huì)被悄悄地忽略。同樣指定的日期也會(huì)被忽略, 除非使用了一個(gè)包括夏令時(shí)規(guī)則的時(shí)區(qū)名,比如 America/New_York,在這種情況下, 必須指定日期以確定這個(gè)時(shí)間是標(biāo)準(zhǔn)時(shí)間還是夏令時(shí)。 時(shí)區(qū)偏移將記錄在time with time zone中。
Table 8-11. 時(shí)間輸入
例子 | 描述 |
---|---|
04:05:06.789 | ISO 8601 |
04:05:06 | ISO 8601 |
04:05 | ISO 8601 |
040506 | ISO 8601 |
04:05 AM | 與04:05一樣;AM不影響數(shù)值 |
04:05 PM | 與16:05一樣;輸入小時(shí)數(shù)必須<=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 | 縮寫(xiě)的時(shí)區(qū) |
2003-04-12 04:05:06 America/New_York | 用名字聲明的時(shí)區(qū) |
Table 8-12. 時(shí)區(qū)輸入
例子 | 描述 |
---|---|
PST | 太平洋標(biāo)準(zhǔn)時(shí)間(Pacific Standard Time) |
America/New_York | 完整時(shí)區(qū)名稱(chēng) |
PST8PDT | POSIX風(fēng)格的時(shí)區(qū) |
-8:00 | ISO-8601與PST的偏移 |
-800 | ISO-8601與PST的偏移 |
-8 | ISO-8601與PST的偏移 |
zulu | 軍方對(duì)UTC的縮寫(xiě) |
z | zulu的縮寫(xiě) |
參考Section 8.5.3以獲取如何指定時(shí)區(qū)的更多信息。
時(shí)間戳類(lèi)型的有效輸入由一個(gè)日期和時(shí)間的連接組成, 后面跟著一個(gè)可選的時(shí)區(qū),一個(gè)可選的AD或BC。 另外,AD/BC可以出現(xiàn)在時(shí)區(qū)前面, 但這個(gè)順序并非最佳的。因此
1999-01-08 04:05:06
和:
1999-01-08 04:05:06 -8:00
都是有效的數(shù)值,它是兼容 ISO-8601的。另外, 也支持下面這種使用廣泛的格式;
January 8 04:05:06 1999 PST
被支持。
SQL標(biāo)準(zhǔn)通過(guò)"+"或者"-"是否 存在來(lái)區(qū)分timestamp without time zone和timestamp with time zone文本。因此,根據(jù)標(biāo)準(zhǔn),
TIMESTAMP '2004-10-19 10:23:54'
是一個(gè)timestamp without time zone,而
TIMESTAMP '2004-10-19 10:23:54+02'
是一個(gè)timestamp with time zone。 PostgreSQL從來(lái)不會(huì) 在確定文本的類(lèi)型之前檢查文本內(nèi)容, 因此會(huì)把上面兩個(gè)都看做是timestamp without time zone。 因此要保證把上面的第二個(gè)當(dāng)作timestamp without time zone看待, 就要給它明確的類(lèi)型:
TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'
如果一個(gè)文本已被確定是timestamp without time zone, PostgreSQL將悄悄忽略任何文本中指出的時(shí)區(qū)。 因此,生成的日期/時(shí)間值是從輸入值的日期/時(shí)間字段衍生出來(lái)的,并且沒(méi)有就時(shí)區(qū)進(jìn)行調(diào)整。
對(duì)于timestamp with time zone,內(nèi)部存儲(chǔ)的數(shù)值總是UTC(全球統(tǒng)一時(shí)間,以前也叫格林威治時(shí)間 GMT)。 如果一個(gè)輸入值有明確的時(shí)區(qū)聲明,那么它將用該時(shí)區(qū)合適的偏移量轉(zhuǎn)換成 UTC 。 如果在輸入字符串里沒(méi)有時(shí)區(qū)聲明, 那么它就假設(shè)是在系統(tǒng)的timezone參數(shù)里的那個(gè)時(shí)區(qū),然后使用這個(gè)timezone時(shí)區(qū)轉(zhuǎn)換成UTC。
如果輸出一個(gè)timestamp with time zone,那么它總是從UTC轉(zhuǎn)換成當(dāng)前的timezone時(shí)區(qū), 并且顯示為該時(shí)區(qū)的本地時(shí)間。要看其它時(shí)區(qū)的該時(shí)間, 要么修改timezone, 要么使用AT TIME ZONE構(gòu)造 (參閱Section 9.9.3)。
在timestamp without time zone和timestamp with time zone之間的 轉(zhuǎn)換通常假設(shè)timestamp without time zone數(shù)值應(yīng)該以timezone本地時(shí)間的形式接受或者寫(xiě)出。 其它的時(shí)區(qū)引用可以用AT TIME ZONE的方式為轉(zhuǎn)換聲明。
PostgreSQL為方便起見(jiàn)支持在 Table 8-13里面顯示的幾個(gè)特殊輸入值。 值infinity 和 -infinity是特別在系統(tǒng)內(nèi)部表示的, 并且將按照同樣的方式顯示;但是其它的都只是符號(hào)縮寫(xiě), 在讀取的時(shí)候?qū)⒈晦D(zhuǎn)換成普通的日期/時(shí)間值。 特別是now和相關(guān)的字符串在讀取的時(shí)候就被轉(zhuǎn)換成對(duì)應(yīng)的數(shù)值。 所有這些值在 SQL 命令里當(dāng)作普通常量對(duì)待時(shí),都需要寫(xiě)在單引號(hào)里面。
Table 8-13. 特殊日期/時(shí)間輸入
輸入字符串 | 適用類(lèi)型 | 描述 |
---|---|---|
epoch | date, timestamp | 1970-01-01 00:00:00+00 (UNIX系統(tǒng)零時(shí)) |
infinity | date, timestamp | 比任何其它時(shí)間戳都晚 |
-infinity | date, timestamp | 比任何其它時(shí)間戳都早 |
now | date, time, timestamp | 當(dāng)前事務(wù)的開(kāi)始時(shí)間 |
today | date, timestamp | 今日午夜 |
tomorrow | date, timestamp | 明日午夜 |
yesterday | date, timestamp | 昨日午夜 |
allballs | time | 00:00:00.00 UTC |
下列SQL兼容函數(shù)也可以用于獲取對(duì)應(yīng)數(shù)據(jù)類(lèi)型的當(dāng)前時(shí)間值: CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP, LOCALTIME,LOCALTIMESTAMP。 后四個(gè)接受一個(gè)可選的精度聲明(Section 9.9.4)。不過(guò), 請(qǐng)注意這些SQL函數(shù)不是被當(dāng)作數(shù)據(jù)輸入字符串識(shí)別的。
日期/時(shí)間類(lèi)型的輸出格式設(shè)成 ISO 8601(默認(rèn))、SQL(Ingres)、 傳統(tǒng)的POSTGRES(Unix date 格式)、German四種風(fēng)格之一。 SQL標(biāo)準(zhǔn)要求使用ISO 8601格式。"SQL"輸出格式的名字是歷史偶然。 Table 8-14顯示了每種輸出風(fēng)格的例子。 date和time類(lèi)型的輸出當(dāng)然只是給出的例子里面的日期和時(shí)間部分。
Table 8-14. 日期/時(shí)間輸入
風(fēng)格 | 描述 | 例子 |
---|---|---|
ISO | ISO 8601/SQL標(biāo)準(zhǔn) | 1997-12-17 07:37:16-08 |
SQL | 傳統(tǒng)風(fēng)格 | 12/17/1997 07:37:16.00 PST |
POSTGRES | 原始風(fēng)格 | Wed Dec 17 07:37:16 1997 PST |
German | 地區(qū)風(fēng)格 | 17.12.1997 07:37:16.00 PST |
如果聲明了DMY順序,那么在SQL和POSTGRES風(fēng)格里, 日期在月份之前出現(xiàn),否則月份出現(xiàn)在日期之前(參閱Section 8.5.1看看這個(gè)設(shè)置如何影響對(duì)輸入值的解釋)。Table 8-15里有一個(gè)例子。
Table 8-15. 日期順序習(xí)慣
datestyle設(shè)置 | 輸入順序 | 輸入樣例 |
---|---|---|
SQL, DMY | 日/月/年 | 17/12/1997 15:37:16.00 CET |
SQL, MDY | 月/日/年 | 12/17/1997 07:37:16.00 PST |
Postgres, DMY | day日/month月/year年 | Wed 17 Dec 07:37:16 1997 PST |
用戶(hù)可以用SET datestyle命令選取日期/時(shí)間的風(fēng)格,
也可以在配置文件postgresql.conf中的DateStyle參數(shù)中設(shè)置,
或者在服務(wù)器或客戶(hù)端的PGDATESTYLE環(huán)境變量中設(shè)置。
我們也可以用格式化函數(shù)to_char
(參見(jiàn)Section 9.8)來(lái)更靈活地控制時(shí)間/日期地輸出。
時(shí)區(qū)和時(shí)區(qū)習(xí)慣不僅僅受地球幾何形狀的影響,還受到政治決定的影響。 到了19世紀(jì),全球的時(shí)區(qū)變得稍微標(biāo)準(zhǔn)化了些,但是還是易于遭受隨意的修改 ,部分是因?yàn)橄臅r(shí)制規(guī)則。PostgreSQL使用廣泛 使用的zoneinfo時(shí)區(qū)信息數(shù)據(jù)庫(kù)有關(guān)歷史的時(shí)區(qū)規(guī)則。在未來(lái),假設(shè) 是已知的對(duì)于一個(gè)給定的時(shí)區(qū)的最新規(guī)則會(huì)被繼續(xù)無(wú)限期的遵守。
PostgreSQL在典型應(yīng)用中盡可能與SQL的定義相兼容。 但SQL標(biāo)準(zhǔn)在日期/時(shí)間類(lèi)型和功能上有一些奇怪的混淆。 兩個(gè)顯而易見(jiàn)的問(wèn)題是:
date類(lèi)型與時(shí)區(qū)沒(méi)有聯(lián)系,而time類(lèi)型卻有或可以有。 然而,現(xiàn)實(shí)世界的時(shí)區(qū)只有在與時(shí)間和日期都關(guān)聯(lián)時(shí)才有意義, 因?yàn)闀r(shí)間偏移量(時(shí)差)可能因?yàn)閷?shí)行類(lèi)似夏時(shí)制這樣的制度而在一年里有所變化。
缺省的時(shí)區(qū)用一個(gè)數(shù)字常量表示與UTC的偏移(時(shí)差)。 因此,當(dāng)跨DST(夏時(shí)制)界限做日期/時(shí)間算術(shù)時(shí), 我們根本不可能把夏時(shí)制這樣的因素計(jì)算進(jìn)去。
為了克服這些困難,我們建議在使用時(shí)區(qū)的時(shí)候,使用那些同時(shí)包含日期和時(shí)間的日期/時(shí)間類(lèi)型。 我們建議不使用time with time zone類(lèi)型( 盡管PostgreSQL出于合理應(yīng)用以及為了與其它RDBMS兼容的考慮支持這個(gè)類(lèi)型)。 PostgreSQL假設(shè)你用于 任何類(lèi)型的本地時(shí)區(qū)都只包含日期或時(shí)間(而不包含時(shí)區(qū))。
在系統(tǒng)內(nèi)部,所有日期和時(shí)間都用全球統(tǒng)一時(shí)間UTC格式存儲(chǔ), 時(shí)間在發(fā)給客戶(hù)前端前由數(shù)據(jù)庫(kù)服務(wù)器根據(jù)timezone配置參數(shù)聲明的時(shí)區(qū)轉(zhuǎn)換成本地時(shí)間。
PostgreSQL允許使用三種方法指定時(shí)區(qū):
完整的時(shí)區(qū)名,例如America/New_York。 所有可以識(shí)別的時(shí)區(qū)名在pg_timezone_names視圖中列出 (參見(jiàn)Section 45.60)。 PostgreSQL使用廣泛使用的zoneinfo時(shí)區(qū)數(shù)據(jù), 所以這些時(shí)區(qū)名在其它軟件里也能被輕松的識(shí)別。
時(shí)區(qū)縮寫(xiě)。例如PST。 這種縮寫(xiě)名通常只是定義了相對(duì)于UTC的偏移量, 而前一種完整的時(shí)區(qū)名可能還隱含著一組夏時(shí)制轉(zhuǎn)換規(guī)則。 所有可以識(shí)別的時(shí)區(qū)縮寫(xiě)在pg_timezone_abbrevs視圖中列出(參見(jiàn)Section 45.59)。 你不能使用時(shí)區(qū)縮寫(xiě)來(lái)設(shè)置timezone或log_timezone配置參數(shù), 但是你可以在日期/時(shí)間輸入值中結(jié)合AT TIME ZONE操作符使用時(shí)區(qū)縮寫(xiě)。
除完整的時(shí)區(qū)名及其縮寫(xiě)之外,PostgreSQL還接受POSIX風(fēng)格的STDoffset 或 STDoffsetDST格式的時(shí)區(qū), 其中的STD是時(shí)區(qū)縮寫(xiě)、offset是一個(gè)相對(duì)于UTC的小時(shí)偏移量、 DST是一個(gè)可選的夏時(shí)制時(shí)區(qū)縮寫(xiě)(假定相對(duì)于給定的偏移量提前一小時(shí))。 例如,如果EST5EDT不是一個(gè)已識(shí)別的時(shí)區(qū)名,那么它將等同于美國(guó)東部時(shí)間。 如果存在夏時(shí)制時(shí)區(qū)名是當(dāng)前時(shí)區(qū)名, 根據(jù)zoneinfo時(shí)區(qū)數(shù)據(jù)庫(kù)的posixrules條目中相同的夏時(shí)制事務(wù)規(guī)則,可以考慮使用這個(gè)特性。 在一個(gè)PostgreSQL標(biāo)準(zhǔn)安裝中, posixrules與US/Eastern相同,因此POSIX格式的時(shí)區(qū)聲明遵循USA夏時(shí)制規(guī)則。 如果需要,可以通過(guò)替換posixrules文件來(lái)調(diào)整該習(xí)慣。
總之,完整的時(shí)區(qū)名與時(shí)區(qū)縮寫(xiě)在理論與實(shí)踐之間存在差異: 時(shí)區(qū)縮寫(xiě)總是代表一個(gè)相對(duì)于UTC的固定偏移量, 然而大多數(shù)完整的時(shí)區(qū)名隱含著一個(gè)本地夏令時(shí)規(guī)則, 因此就有可能有兩個(gè)相對(duì)于UTC的不同偏移量。
需要警惕的是,由于沒(méi)有合理的時(shí)區(qū)縮寫(xiě)檢查,POSIX格式的時(shí)區(qū)特點(diǎn)能導(dǎo)致靜默的偽輸入。 例如,使用SET TIMEZONE TO FOOBAR0時(shí),實(shí)際上系統(tǒng)使用的是一個(gè)很特別的UTC縮寫(xiě)。 另一個(gè)需要注意的是,在POSIX時(shí)區(qū)名中,積極的偏移用于west格林尼治位置。 在其他地方,PostgreSQL遵循ISO-8601規(guī)定,即積極的時(shí)區(qū)偏移east格林威治。
總體而言,PostgreSQL8.2版本以后時(shí)區(qū)名在所有情況下 都是大小寫(xiě)無(wú)關(guān)的。而之前的版本在某些情況下是大小寫(xiě)敏感的。
無(wú)論是完整的時(shí)區(qū)名還是時(shí)區(qū)縮寫(xiě)都不是硬連接進(jìn)服務(wù)器的, 它們都是從安裝目錄下的.../share/timezone/和.../share/timezonesets/配置文件中獲取的(參見(jiàn)Section B.3)
可以在postgresql.conf文件里設(shè)置timezone配置參數(shù), 或者用任何其它在Chapter 18描述的標(biāo)準(zhǔn)方法。除此之外, 還有好幾種特殊方法可以設(shè)置它:
如果既沒(méi)有在postgresql.conf里也沒(méi)有在命令行開(kāi)關(guān) 上聲明timezone,那么服務(wù)器將試圖使用服務(wù)器主機(jī)上的TZ環(huán)境變量 作為服務(wù)器的缺省時(shí)區(qū)。 如果TZ沒(méi)有定義或者是PostgreSQL不認(rèn)識(shí)的時(shí)區(qū)名, 那么服務(wù)器將試圖通過(guò)檢查C庫(kù)函數(shù)localtime()的行為來(lái)判斷操作系統(tǒng)的缺省時(shí)區(qū)。 缺省時(shí)區(qū)是按照最接近PostgreSQL的已知時(shí)區(qū)的原則來(lái)選擇的。 (如果沒(méi)有指定,這些規(guī)則也可以用來(lái)選擇默認(rèn)值log_timezone)。
使用SQL命令SET TIME ZONE為會(huì)話(huà)設(shè)置時(shí)區(qū), 這是SET TIMEZONE TO的一個(gè)可選的拼寫(xiě)方式, 更加兼容標(biāo)準(zhǔn)。
如果在客戶(hù)端設(shè)置了PGTZ環(huán)境變量, 那么libpq在連接時(shí)將使用 這個(gè)環(huán)境變量給后端發(fā)送一個(gè)SET TIME ZONE命令。
interval類(lèi)型值可以用下面的詳細(xì)語(yǔ)法寫(xiě):
[@] quantity unit [quantity unit...] [direction]
這里quantity是一個(gè)數(shù)字(可能已標(biāo)記); unit可以是microsecond,millisecond,second, minute,hour,day,week, month,year,decade,century,millennium或這些單位的縮寫(xiě)或復(fù)數(shù)。 direction可以是ago或?yàn)榭铡?tt class="LITERAL">@標(biāo)記是可選的。ago否定所有。 如果IntervalStyle設(shè)置為postgres_verbose,那么這個(gè)語(yǔ)法同樣用于間隔輸入。
可以在沒(méi)有明確單位標(biāo)記的情況下聲明天,小時(shí),分鐘和秒。 例如,'1 12:59:10'等同于'1 day 12 hours 59 min 10 sec'。 同樣,可以用一個(gè)破折號(hào)來(lái)聲明一個(gè)年和月的組合,例如'200-10'等同于'200 years 10 months'。 (事實(shí)上,SQL標(biāo)準(zhǔn)值允許短的格式,并且當(dāng) IntervalStyle設(shè)置為sql_standard時(shí),用于輸出)。
要么使用ISO 8601標(biāo)準(zhǔn)4.4.3.2的"format with designators",要么使用4.4.3.3的"alternative format",間隔值可以寫(xiě)為ISO 8601的時(shí)間間隔。 格式如下:
P quantity unit [ quantity unit ...] [ T [ quantity unit ...]]
字符串必須以P開(kāi)始,并且可以含有一個(gè)T用以指明一天中時(shí)間的格式。 可用單位的縮寫(xiě)在Table 8-16有說(shuō)明。 可以忽略單位,也可以以任意順序聲明,但單位小于一天時(shí)必須在T之后。 尤其M的含義依賴(lài)于它在T之前或之后。
Table 8-16. ISO8601間隔單位的縮寫(xiě)
縮寫(xiě) | 含義 |
---|---|
Y | 年 |
M | 月(日期部分) |
W | 周 |
D | 日 |
H | 小時(shí) |
M | 分鐘(時(shí)間部分) |
S | 秒 |
以縮寫(xiě)格式:
P [ years-months-days ] [ T hours:minutes:seconds ]
一個(gè)字符串必須以P開(kāi)始,然后以T隔開(kāi)日期和時(shí)間。 給出的值是如同ISO 8601日期的數(shù)字。
當(dāng)用fields規(guī)范寫(xiě)一個(gè)時(shí)間間隔常熟,或?qū)⒁粋€(gè)字符串標(biāo)記為用fields規(guī)范定義的一個(gè)間隔柱時(shí), 未標(biāo)記單位的解釋由fields解釋。如INTERVAL '1' YEAR讀作1年,然而INTERVAL '1'代表1秒。 同樣,fields規(guī)范中最低有效字段值規(guī)定會(huì)被靜默的忽略。如,INTERVAL '1 day 2:03:04' HOUR TO MINUTE會(huì)導(dǎo)致刪除 秒字段,而不是天字段。
根據(jù)SQL標(biāo)準(zhǔn),間隔值的所有字段必須有相同的符號(hào),因此前導(dǎo)負(fù)號(hào)可以用于所有字段; 如'-1 2:03:04'中負(fù)號(hào)同時(shí)應(yīng)用于天和小時(shí)/分鐘/秒。 PostgreSQL允許字段有不同的標(biāo)記,并且傳統(tǒng)上,文本表述中的每個(gè)字段會(huì)被認(rèn)為是獨(dú)立標(biāo)記的, 因此在這個(gè)例子中的小時(shí)/分鐘/秒被認(rèn)為是允許的。如果IntervalStyle被設(shè)置為sql_standard,那么前導(dǎo)標(biāo)記被認(rèn)為是應(yīng)用于所有字段的 (當(dāng)然前提是沒(méi)有再出現(xiàn)其他標(biāo)記),否則會(huì)使用傳統(tǒng)的PostgreSQL解釋。為了避免這種奇異,建議為每個(gè)字段附上一個(gè)明確的標(biāo)記。
PostgreSQL內(nèi)部,interval值被存儲(chǔ)為月,日,秒的格式,這是因?yàn)樵轮邪欤⑶胰绻M(jìn)行了夏令時(shí)調(diào)整,那么一天可以有23或25小時(shí)。
當(dāng)秒字段可以存儲(chǔ)分?jǐn)?shù)時(shí),月和天字段可以是整數(shù)型。由于時(shí)間間隔通常是由常量字符串或timestamp減法來(lái)定義的,
這種存儲(chǔ)方法在大多數(shù)情況下很有效。justify_days
和justify_hours
函數(shù)可用于調(diào)整溢出正常范圍值的天和小時(shí)。
在詳細(xì)的輸出格式,以及更緊湊的輸入格式中,字段值可以有小數(shù)部分,例如'1.5 week'或'01:02:03.45'。 這種輸入被轉(zhuǎn)換成恰當(dāng)?shù)脑拢旌兔雭?lái)存儲(chǔ)。由于這樣會(huì)產(chǎn)生小數(shù)的月或天,因此在低階字段中引入了分?jǐn)?shù),用以1 month = 30 days 和 1 day = 24 hours的轉(zhuǎn)換。 例如,'1.5 month'即1個(gè)月15天。輸出中,只有秒可以寫(xiě)成分?jǐn)?shù)形式。
Table 8-17中有一些有效的interval輸入的例子。
Table 8-17. 間隔輸入
示例 | 說(shuō)明 |
---|---|
1-2 | SQL標(biāo)準(zhǔn)格式:一年兩個(gè)月 |
3 4:05:06 | SQL標(biāo)準(zhǔn)格式:3天4小時(shí)5分6秒 |
1 year 2 months 3 days 4 hours 5 minutes 6 seconds | 傳統(tǒng)Postgres格式: 1年2個(gè)月3天4小時(shí)5分鐘6秒 |
P1Y2M3DT4H5M6S | ISO 8601 "帶標(biāo)識(shí)符格式":與上面相同含義 |
P0001-02-03T04:05:06 | ISO 8601 "縮寫(xiě)格式":與上面相同含義 |
間隔類(lèi)型的輸出格式可以用命令SET intervalstyle設(shè)置為下面四種類(lèi)型:sql_standard,postgres,postgres_verbose或iso_8601 默認(rèn)是postgres格式,Table 8-18中有每種格式的示例。
sql_standard格式產(chǎn)生的輸出結(jié)果符合SQL的區(qū)間字符串標(biāo)準(zhǔn), 如果間隔值滿(mǎn)足標(biāo)準(zhǔn)的限制(無(wú)論年-月,或只有天-時(shí)間,沒(méi)有積極和消極的構(gòu)成的混合)。 否則類(lèi)似一個(gè)標(biāo)準(zhǔn)年-月文本字符串后跟有一個(gè)天-時(shí)間文本字符串的輸出,帶有添加明確標(biāo)記的消除歧義混合信號(hào)的時(shí)間間隔。
postgres格式的輸出與PostgreSQL8.4(此時(shí)DateStyle參數(shù)設(shè)置為ISO)之前的輸出是一致的。
postgres格式的輸出與PostgreSQL8.4(此時(shí)DateStyle參數(shù)設(shè)置為非ISO輸出)之前的輸出是一致的
iso_8601格式的輸出與ISO 8601標(biāo)準(zhǔn)4.4.3.2節(jié)中的"format with designators"一致。
Table 8-18. 間隔輸出格式示例
格式 | 年-月區(qū)間 | 天-時(shí)間區(qū)間 | 混合區(qū)間 |
---|---|---|---|
sql_standard | 1-2 | 3 4:05:06 | -1-2 +3 -4:05:06 |
postgres | 1年2個(gè)月 | 3天04:05:06 | -1年-2個(gè)月+3天-04:05:06 |
postgres_verbose | @1年2個(gè)月 | @3天4小時(shí)5分6秒 | @1年2個(gè)月-3天4小時(shí)5分6秒以前 |
iso_8601 | P1Y2M | P3DT4H5M6S | P-1Y-2M3DT-4H-5M-6S |
PostgreSQL 使用儒略歷法計(jì)算所有日期/時(shí)間, 假設(shè)一年的長(zhǎng)度是365.2425天。這個(gè)方法可以很精確地預(yù)計(jì)/計(jì)算從公元前4713年到很久的未來(lái)的任意一天的日期。
19世紀(jì)以前的日期傳統(tǒng)(歷法)只是對(duì)一些趣味讀物有意義, 而在我們這里好像沒(méi)有充分的理由把它們編碼入日期/時(shí)間控制器里面去。