支援的版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

9.8. 資料類型格式化函式 #

PostgreSQL 格式化函式提供了一組強大的工具,用於將各種資料類型(日期/時間、整數、浮點數、數值)轉換為格式化的字串,以及將格式化的字串轉換為特定的資料類型。 表 9.26 列出了這些函式。 這些函式都遵循一個通用的呼叫慣例:第一個引數是要格式化的值,第二個引數是定義輸出或輸入格式的模板。

表 9.26. 格式化函式

函式

描述

範例

to_char ( timestamp, text ) → text

to_char ( timestamp with time zone, text ) → text

根據給定的格式將時間戳記轉換為字串。

to_char(timestamp '2002-04-20 17:31:12.66', 'HH12:MI:SS')05:31:12

to_char ( interval, text ) → text

根據給定的格式將時間間隔轉換為字串。

to_char(interval '15h 2m 12s', 'HH24:MI:SS')15:02:12

to_char ( numeric_type, text ) → text

根據給定的格式將數字轉換為字串;適用於 integerbigintnumericrealdouble precision

to_char(125, '999')125

to_char(125.8::real, '999D9')125.8

to_char(-125.8, '999D99S')125.80-

to_date ( text, text ) → date

根據給定的格式將字串轉換為日期。

to_date('05 Dec 2000', 'DD Mon YYYY')2000-12-05

to_number ( text, text ) → numeric

根據給定的格式將字串轉換為數值。

to_number('12,454.8-', '99G999D9S')-12454.8

to_timestamp ( text, text ) → timestamp with time zone

根據給定的格式將字串轉換為時間戳記。(另請參閱表 9.33中的to_timestamp(double precision)。)

to_timestamp('05 Dec 2000', 'DD Mon YYYY')2000-12-05 00:00:00-05


提示

to_timestampto_date 的存在是為了處理無法透過簡單轉換來轉換的輸入格式。 對於大多數標準日期/時間格式,只需將來源字串轉換為所需的資料類型即可,而且更容易。 同樣地,對於標準數值表示法,to_number 是不必要的。

to_char 輸出模板字串中,存在某些模式,這些模式會被識別並根據給定的值替換為適當格式化的資料。 任何不是模板模式的文字都會被簡單地逐字複製。 同樣地,在輸入模板字串(對於其他函式)中,模板模式識別要由輸入資料字串提供的數值。 如果模板字串中存在不是模板模式的字元,則輸入資料字串中的相應字元將被簡單地跳過(無論它們是否等於模板字串字元)。

表 9.27 顯示了可用於格式化日期和時間值的模板模式。

表 9.27. 日期/時間格式化的模板模式

模式 描述
HH 一天中的小時 (01–12)
HH12 一天中的小時 (01–12)
HH24 一天中的小時 (00–23)
MI 分鐘 (00–59)
SS 秒 (00–59)
MS 毫秒 (000–999)
US 微秒 (000000–999999)
FF1 十分之一秒 (0–9)
FF2 百分之一秒 (00–99)
FF3 毫秒 (000–999)
FF4 十分之一毫秒 (0000–9999)
FF5 百分之一毫秒 (00000–99999)
FF6 微秒 (000000–999999)
SSSS, SSSSS 午夜後的秒數 (0–86399)
AM, am, PMpm 上午/下午指示符 (不含句點)
A.M., a.m., P.M.p.m. 上午/下午指示符 (含句點)
Y,YYY 年份 (4 位或更多位數),含逗號
YYYY 年份 (4 位或更多位數)
YYY 年份的最後 3 位數
YY 年份的最後 2 位數
Y 年份的最後 1 位數
IYYY ISO 8601 週編號年份 (4 位或更多位數)
IYY ISO 8601 週編號年份的最後 3 位數
IY ISO 8601 週編號年份的最後 2 位數
I ISO 8601 週編號年份的最後 1 位數
BC, bc, ADad 紀元指示符 (不含句點)
B.C., b.c., A.D.a.d. 紀元指示符 (含句點)
MONTH 完整大寫月份名稱 (空白填補至 9 個字元)
Month 完整首字大寫月份名稱 (空白填補至 9 個字元)
month 完整小寫月份名稱 (空白填補至 9 個字元)
MON 縮寫大寫月份名稱 (英文為 3 個字元,本地化長度會有所不同)
Mon 縮寫首字大寫月份名稱 (英文為 3 個字元,本地化長度會有所不同)
mon 縮寫小寫月份名稱 (英文為 3 個字元,本地化長度會有所不同)
MM 月份數字 (01–12)
DAY 完整大寫日期名稱 (空白填補至 9 個字元)
Day 完整首字大寫日期名稱 (空白填補至 9 個字元)
day 完整小寫日期名稱 (空白填補至 9 個字元)
DY 縮寫大寫日期名稱 (英文為 3 個字元,本地化長度會有所不同)
Dy 縮寫首字大寫日期名稱 (英文為 3 個字元,本地化長度會有所不同)
dy 縮寫小寫日期名稱 (英文為 3 個字元,本地化長度會有所不同)
DDD 一年中的第幾天 (001–366)
IDDD ISO 8601 週編號年份的第幾天 (001–371;一年中的第 1 天是第一個 ISO 週的星期一)
DD 月份中的第幾天 (01–31)
D 星期幾,星期日 (1) 到星期六 (7)
ID ISO 8601 星期幾,星期一 (1) 到星期日 (7)
W 月份中的第幾週 (1–5) (第一週從該月的第一天開始)
WW 一年中的第幾週 (1–53) (第一週從該年的第一天開始)
IW ISO 8601 週編號年份的第幾週 (01–53;一年中的第一個星期四是第 1 週)
CC 世紀 (2 位數字) (二十一世紀從 2001-01-01 開始)
J 儒略日 (自西元前 4714 年 11 月 24 日當地午夜以來的整數天數;請參閱第 B.7 節)
Q 季度
RM 大寫羅馬數字月份 (I–XII;I=一月)
rm 小寫羅馬數字月份 (i–xii;i=一月)
TZ 大寫時區縮寫
tz 小寫時區縮寫
TZH 時區小時
TZM 時區分鐘
OF 與 UTC 的時區偏移量 (HHHH:MM)

修飾符可以應用於任何範本模式,以改變其行為。例如,FMMonth 是具有 FM 修飾符的 Month 模式。表 9.28 顯示了日期/時間格式化的修飾符模式。

表 9.28. 日期/時間格式化的範本模式修飾符

修飾符 描述 範例
FM 前綴 填滿模式 (抑制前導零和填補空格) FMMonth
TH 後綴 大寫序數後綴 DDTH,例如,12TH
th 後綴 小寫序數後綴 DDth,例如,12th
FX 前綴 固定格式全域選項 (請參閱使用說明) FX Month DD Day
TM 前綴 翻譯模式 (根據 lc_time 使用本地化的日期和月份名稱) TMMonth
SP 後綴 拼字模式 (尚未實作) DDSP

日期/時間格式化的使用說明

  • FM 抑制前導零和尾隨空格,否則會添加這些零和空格以使模式的輸出成為固定寬度。在 PostgreSQL 中,FM 僅修改下一個規範,而在 Oracle 中,FM 影響所有後續規範,並且重複的 FM 修飾符會切換填滿模式的開啟和關閉。

  • 無論是否指定 FMTM 都會抑制尾隨空格。

  • to_timestampto_date 忽略輸入中的字母大小寫;因此,例如,MONMonmon 都接受相同的字串。當使用 TM 修飾符時,大小寫折疊會根據函數的輸入定序規則來完成 (請參閱 第 23.2 節)。

  • 除非使用 FX 選項,否則 to_timestampto_date 會跳過輸入字串開頭和日期和時間值周圍的多個空格。例如,to_timestamp(' 2000    JUN', 'YYYY MON')to_timestamp('2000 - JUN', 'YYYY-MON') 可以正常工作,但 to_timestamp('2000    JUN', 'FXYYYY MON') 會傳回錯誤,因為 to_timestamp 僅預期一個空格。FX 必須指定為範本中的第一個項目。

  • to_timestampto_date 的樣板字串中,分隔符號(空格或非字母/非數字字元)會比對輸入字串中的任何單一分隔符號,或被略過,除非使用 FX 選項。例如,to_timestamp('2000JUN', 'YYYY///MON')to_timestamp('2000/JUN', 'YYYY MON') 可以運作,但 to_timestamp('2000//JUN', 'YYYY/MON') 會傳回錯誤,因為輸入字串中的分隔符號數量超過樣板中的分隔符號數量。

    如果指定了 FX,樣板字串中的分隔符號會完全比對輸入字串中的一個字元。但請注意,輸入字串字元不一定要與樣板字串中的分隔符號相同。例如,to_timestamp('2000/JUN', 'FXYYYY MON') 可以運作,但 to_timestamp('2000/JUN', 'FXYYYY  MON') 會傳回錯誤,因為樣板字串中的第二個空格會佔用輸入字串中的字母 J

  • TZH 樣板模式可以比對帶正負號的數字。如果沒有 FX 選項,負號可能會不明確,並可能被解釋為分隔符號。此不明確性會以下列方式解決:如果樣板字串中 TZH 前面的分隔符號數量少於輸入字串中負號前面的分隔符號數量,則負號會被解釋為 TZH 的一部分。否則,負號會被視為值之間的分隔符號。例如,to_timestamp('2000 -10', 'YYYY TZH') 會將 -10 比對到 TZH,但 to_timestamp('2000 -10', 'YYYY  TZH') 會將 10 比對到 TZH

  • 一般文字允許出現在 to_char 樣板中,並會逐字輸出。您可以將子字串放在雙引號中,強制將其解釋為文字,即使它包含樣板模式也是如此。例如,在 '"Hello Year "YYYY' 中,YYYY 會被年份資料取代,但 Year 中的單個 Y 則不會。在 to_dateto_numberto_timestamp 中,文字和雙引號字串會導致跳過字串中包含的字元數;例如 "XX" 會跳過兩個輸入字元(無論它們是否為 XX)。

    提示

    PostgreSQL 12 之前,可以使用非字母或非數字字元跳過輸入字串中的任意文字。例如,to_timestamp('2000y6m1d', 'yyyy-MM-DD') 過去可以運作。現在您只能使用字母字元來達到此目的。例如,to_timestamp('2000y6m1d', 'yyyytMMtDDt')to_timestamp('2000y6m1d', 'yyyy"y"MM"m"DD"d"') 會跳過 ymd

  • 如果您希望在輸出中包含雙引號,則必須在其前面加上反斜線,例如 '\"YYYY Month\"'。反斜線在雙引號字串之外沒有其他特殊意義。在雙引號字串中,反斜線會使下一個字元被逐字採用,無論它是什麼(但除非下一個字元是雙引號或另一個反斜線,否則這沒有特殊效果)。

  • to_timestampto_date 中,如果年份格式規範少於四位數,例如 YYY,並且提供的年份少於四位數,則年份將調整為最接近 2020 年的年份,例如,95 會變成 1995 年。

  • to_timestampto_date 中,負年份被視為表示西元前 (BC)。如果您同時寫入負年份和明確的 BC 欄位,您會再次得到西元 (AD)。輸入年份零被視為西元前 1 年。

  • to_timestampto_date 中,當處理超過 4 位數的年份時,YYYY 轉換有一個限制。您必須在 YYYY 之後使用一些非數字字元或樣板,否則年份始終會被解釋為 4 位數。例如(年份為 20000):to_date('200001130', 'YYYYMMDD') 將被解釋為 4 位數的年份;而是使用年份之後的非數字分隔符號,例如 to_date('20000-1130', 'YYYY-MMDD')to_date('20000Nov30', 'YYYYMonDD')

  • to_timestampto_date 中,如果存在 YYYYYYYY,YYY 欄位,則會接受但忽略 CC(世紀)欄位。如果 CCYYY 一起使用,則結果會計算為指定世紀中的那一年。如果指定了世紀但未指定年份,則假定為該世紀的第一年。

  • to_timestampto_date 中,星期名稱或數字(DAYD 和相關欄位類型)會被接受,但在計算結果時會被忽略。對於季度 (Q) 欄位也是如此。

  • to_timestampto_date 中,可以使用以下兩種方式之一指定 ISO 8601 週數日期(與格里曆日期不同)

    • 年份、週數和星期幾:例如 to_date('2006-42-4', 'IYYY-IW-ID') 傳回日期 2006-10-19。如果您省略星期幾,則假定為 1(星期一)。

    • 年份和一年中的第幾天:例如 to_date('2006-291', 'IYYY-IDDD') 也會傳回 2006-10-19

    嘗試使用 ISO 8601 週數欄位和格里曆日期欄位的混合來輸入日期是沒有意義的,並且會導致錯誤。在 ISO 8601 週數年份的上下文中,「月份」或「月份中的日期」的概念沒有意義。在格里曆年份的上下文中,ISO 週沒有意義。

    注意

    雖然 to_date 會拒絕格里曆日期和 ISO 週數日期欄位的混合,但 to_char 不會,因為像 YYYY-MM-DD (IYYY-IDDD) 這樣的輸出格式規範可能很有用。但請避免寫入像 IYYY-MM-DD 這樣的程式碼;這會在年初附近產生令人意外的結果。(請參閱第 9.9.1 節,以取得更多資訊。)

  • to_timestamp 函數中,毫秒 (MS) 或微秒 (US) 欄位被用作小數點後的秒數。例如,to_timestamp('12.3', 'SS.MS') 並非 3 毫秒,而是 300 毫秒,因為轉換會將其視為 12 + 0.3 秒。因此,對於 SS.MS 格式,輸入值 12.312.3012.300 指定了相同的毫秒數。要得到三毫秒,必須寫成 12.003,轉換會將其視為 12 + 0.003 = 12.003 秒。

    這是一個更複雜的例子:to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') 是 15 小時、12 分鐘和 2 秒 + 20 毫秒 + 1230 微秒 = 2.021230 秒。

  • to_char(..., 'ID') 的星期幾編號與 extract(isodow from ...) 函數的編號相符,但 to_char(..., 'D') 的編號與 extract(dow from ...) 的星期幾編號不相符。

  • to_char(interval)HHHH12 格式化為 12 小時制時鐘上顯示的樣子,例如,零小時和 36 小時都輸出為 12,而 HH24 輸出完整的小時值,在 interval 值中可能超過 23。

表 9.29 顯示了可用於格式化數值的樣板模式。

表 9.29. 數值格式化的樣板模式

模式 描述
9 數位位置(若不重要則可省略)
0 數位位置(即使不重要也不會省略)
. (句點) 小數點
, (逗號) 群組(千位)分隔符
PR 角括號中的負值
S 錨定到數字的符號(使用 locale)
L 貨幣符號(使用 locale)
D 小數點(使用 locale)
G 群組分隔符(使用 locale)
MI 指定位置的減號(如果數字 < 0)
PL 指定位置的加號(如果數字 > 0)
SG 指定位置的加/減號
RN 羅馬數字(輸入介於 1 和 3999 之間)
THth 序數後綴
V 移動指定的數位數量(請參閱注意事項)
EEEE 科學記號表示法的指數

數值格式化的使用注意事項

  • 0 指定一個始終會被印出的數位位置,即使它包含前導/尾隨零。9 也指定一個數位位置,但如果它是前導零,它將被一個空格替換,而如果它是尾隨零並且指定了填充模式,它將被刪除。(對於 to_number(),這兩個模式字元是等效的。)

  • 如果格式提供的有效位數少於要格式化的數字,to_char() 會將數字四捨五入到指定的有效位數。

  • 模式字元 SLDG 表示由目前 locale 定義的符號、貨幣符號、小數點和千位分隔符(請參閱 lc_monetarylc_numeric)。模式字元句點和逗號表示那些確切的字元,具有小數點和千位分隔符的含義,而與 locale 無關。

  • 如果在 to_char() 的模式中沒有明確規定符號,則會為符號保留一欄,並且它會錨定到(出現在數字的左側)。如果 S 出現在某些 9 的左側,它也會同樣錨定到數字。

  • 使用 SGPLMI 格式化的符號不會錨定到數字;例如,to_char(-12, 'MI9999') 產生 '-  12',但 to_char(-12, 'S9999') 產生 '  -12'。(Oracle 實作不允許在 9 之前使用 MI,而是要求 9MI 之前。)

  • TH 不會轉換小於零的值,也不會轉換小數。

  • PLSGTHPostgreSQL 擴充功能。

  • to_number 中,如果使用非資料樣板模式(例如 LTH),則會跳過對應數量的輸入字元,無論它們是否符合樣板模式,除非它們是資料字元(也就是數字、符號、小數點或逗號)。例如,TH 會跳過兩個非資料字元。

  • 帶有 to_charV 將輸入值乘以 10^n,其中 nV 後面的數位數量。帶有 to_numberV 以類似的方式除。 to_charto_number 不支援將 V 與小數點結合使用(例如,不允許使用 99.9V99)。

  • EEEE(科學記號表示法)不能與任何其他格式化模式或修飾符組合使用,除了數字和小數點模式,並且必須位於格式字串的末尾(例如,9.99EEEE 是一個有效的模式)。

某些修飾符可以應用於任何樣板模式以更改其行為。例如,FM99.99 是帶有 FM 修飾符的 99.99 模式。 表 9.30 顯示了數值格式化的修飾符模式。

表 9.30. 數值格式化的樣板模式修飾符

修飾符 描述 範例
FM 前綴 填充模式(抑制尾隨零和填充空白) FM99.99
TH 後綴 大寫序數後綴 999TH
th 後綴 小寫序數後綴 999th

表 9.31 顯示了 to_char 函數的一些使用範例。

表 9.31. to_char 範例

運算式 結果
to_char(current_timestamp, 'Day, DD  HH12:MI:SS') 'Tuesday  , 06  05:39:18'
to_char(current_timestamp, 'FMDay, FMDD  HH12:MI:SS') 'Tuesday, 6  05:39:18'
to_char(current_timestamp AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"') '2022-12-06T05:39:18Z', ISO8601 擴充格式
to_char(-0.1, '99.99') '  -.10'
to_char(-0.1, 'FM9.99') '-.1'
to_char(-0.1, 'FM90.99') '-0.1'
to_char(0.1, '0.9') ' 0.1'
to_char(12, '9990999.9') '    0012.0'
to_char(12, 'FM9990999.9') '0012.'
to_char(485, '999') ' 485'
to_char(-485, '999') '-485'
to_char(485, '9 9 9') ' 4 8 5'
to_char(1485, '9,999') ' 1,485'
to_char(1485, '9G999') ' 1 485'
to_char(148.5, '999.999') ' 148.500'
to_char(148.5, 'FM999.999') '148.5'
to_char(148.5, 'FM999.990') '148.500'
to_char(148.5, '999D999') ' 148,500'
to_char(3148.5, '9G999D999') ' 3 148,500'
to_char(-485, '999S') '485-'
to_char(-485, '999MI') '485-'
to_char(485, '999MI') '485 '
to_char(485, 'FM999MI') '485'
to_char(485, 'PL999') '+485'
to_char(485, 'SG999') '+485'
to_char(-485, 'SG999') '-485'
to_char(-485, '9SG99') '4-85'
to_char(-485, '999PR') '<485>'
to_char(485, 'L999') 'DM 485'
to_char(485, 'RN') '        CDLXXXV'
to_char(485, 'FMRN') 'CDLXXXV'
to_char(5.2, 'FMRN') 'V'
to_char(482, '999th') ' 482nd'
to_char(485, '"Good number:"999') 'Good number: 485'
to_char(485.8, '"Pre:"999" Post:" .999') 'Pre: 485 Post: .800'
to_char(12, '99V999') ' 12000'
to_char(12.4, '99V999') ' 12400'
to_char(12.45, '99V9') ' 125'
to_char(0.0004859, '9.99EEEE') ' 4.86e-04'

提交更正

如果您在文件中發現任何不正確、與特定功能的使用經驗不符或需要進一步說明之處,請使用此表格來回報文件問題。