2025年9月25日: PostgreSQL 18 釋出!
支援版本: 當前 (18) / 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

根據給定的格式將數字轉換為字串;適用於 integer, bigint, numeric, real, double 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 天是第一週的星期一)
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 修飾符會切換填充模式的開啟和關閉。

  • TM 抑制尾隨空格,無論是否指定了 FM

  • to_timestampto_date 忽略輸入的字母大小寫;因此,例如 MONMonmon 都接受相同的字串。使用 TM 修飾符時,根據函式輸入排序規則(參見 23.2 節)進行大小寫摺疊。

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

  • 除非使用了 FX 選項,否則 to_timestampto_date 的模板字串中的分隔符(空格或非字母/非數字字元)會匹配輸入字串中的任何單個分隔符或被跳過。例如,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 欄位,則會再次得到公元。年份零被視為公元前 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) 以 12 小時制格式化 HHHH12,例如零小時和 36 小時都輸出為 12,而 HH24 輸出完整的小時值,該值可以超過 interval 值中的 23。

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

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

模式 描述
9 數字位置(如果無符號則可省略)
0 數字位置(即使無符號也保留)
. (句點) 小數點
, (逗號) 分組(千位)分隔符
PR 用尖括號表示的負值
S 符號固定在數字上(使用區域設定)
L 貨幣符號(使用區域設定)
D 小數點(使用區域設定)
G 分組分隔符(使用區域設定)
MI 在指定位置的負號(如果數字 < 0)
PL 在指定位置的正號(如果數字 > 0)
SG 在指定位置的正負號
RNrn 羅馬數字(1 到 3999 之間的值)
THth 序數字尾
V 移動指定位數的數字(參見說明)
EEEE 科學計數法的指數

數值格式化用法說明

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

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

  • 模式字元 SLDG 代表當前區域設定定義的符號、貨幣符號、小數點和千位分隔符(參見 lc_monetarylc_numeric)。模式字元句點和逗號代表那些確切的字元,分別具有小數點和千位分隔符的含義,與區域設定無關。

  • 如果在 to_char() 的模式中沒有明確提供符號,則會保留一個列用於符號,並將其錨定在數字的左側(緊鄰數字)。如果 S 出現在一些 9 的左側,它也會錨定在數字上。

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

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

  • PLSGTH 是 PostgreSQL 的擴充套件。

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

  • Vto_char 結合使用時,會將輸入值乘以 10^n,其中 nV 後面的數字位數。 Vto_number 結合使用時,會以類似的方式進行除法。 V 可以被視為標記輸入或輸出字串中隱式小數點的位置。to_charto_number 不支援將 V 與小數點組合使用(例如,不允許 99.9V99)。

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

  • to_number() 中,RN 模式將羅馬數字(標準形式)轉換為數字。輸入不區分大小寫,因此 RNrn 是等效的。RN 不能與任何其他格式模式或修飾符組合使用,除了 FM,後者僅適用於 to_char(),在 to_number() 中被忽略。

某些修飾符可應用於任何模板模式以更改其行為。例如,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'

提交更正

如果您在文件中發現任何不正確、不符合您對特定功能的使用經驗或需要進一步闡明的內容,請使用 此表單 報告文件問題。