本文中含有需要您注意的重要提示信息,忽略該信息可能對您的業務造成影響,請務必仔細閱讀。
本文介紹了PolarDB PostgreSQL版(兼容Oracle)支持的數據類型格式化函數。
本數據庫格式化函數提供一套強大的工具用于把各種數據類型 (日期/時間、整數、浮點、數字) 轉換成格式化的字符串以及反過來從格式化的字符串轉換成指定的數據類型。格式化函數表列出了這些函數。這些函數都遵循一個公共的調用規范: 第一個參數是待格式化的值,而第二個是一個定義輸出或輸入格式的模板。
格式化函數
根據給定的格式將時間戳轉換為字符串。
|
根據給定的格式將間隔轉換為字符串。
|
根據給定的格式將數字轉換為字符串;適用于
|
根據給定的格式將字符串轉換為日期。
|
根據給定的格式將字符串轉換為數字。
|
根據給定的格式將字符串轉換為時間戳。
|
to_timestamp
和to_date
存在的目的是為了處理無法用簡單造型轉換的輸入格式。對于大部分標準的日期/時間格式,簡單地把源字符串造型成所需的數據類型是可以的,并且簡單很多。類似地,對于標準的數字表示形式,to_number
也是沒有必要的。
在一個to_char
輸出模板串中,一些特定的模式可以被識別并且被替換成基于給定值的被恰當地格式化的數據。任何不屬于模板模式的文本都簡單地照字面拷貝。同樣,在一個輸入模板串里(對其他函數),模板模式標識由輸入數據串提供的值。如果在模板字符串中有不是模板模式的字符,輸入數據字符串中的對應字符會被簡單地跳過(不管它們是否等于模板字符串字符)。
用于日期/時間格式化的模板模式表展示了可以用于格式化日期和時間值的模版。
用于日期/時間格式化的模板模式
模式 | 描述 |
| 一天中的小時(01–12) |
| 一天中的小時(01–12) |
| 一天中的小時(00–23) |
| 分鐘 (00–59) |
| 秒 (00–59) |
| 毫秒 (000–999) |
| 微秒 (000000–999999) |
| 十分之一秒 (0–9) |
| 百分之一秒 (00–99) |
| 毫秒 (000–999) |
| 十分之一毫秒 (0000–9999) |
| 百分之一毫秒 (00000–99999) |
| 微秒 (000000–999999) |
| 午夜后的秒 (0–86399) |
| 正午指示器(不帶句號) |
| 正午指示器(帶句號) |
| 帶逗號的年(4 位或者更多位) with comma |
| 年(4 位或者更多位) |
| 年的最后 3 位數字 |
| 年的最后 2 位數字 |
| 年的最后 1 位數字 |
| ISO 8601 周編號方式的年(4 位或更多位) |
| ISO 8601 周編號方式的年的最后 3 位數字 |
| ISO 8601 周編號方式的年的最后 2 位數字 |
| ISO 8601 周編號方式的年的最后 1 位數字 |
| 紀元指示器(不帶句號) |
| 紀元指示器(帶句號) |
| 全大寫形式的月名(空格補齊到 9 字符) |
| 全首字母大寫形式的月名(空格補齊到 9 字符) |
| 全小寫形式的月名(空格補齊到 9 字符) |
| 簡寫的大寫形式的月名(英文 3 字符,本地化長度可變) |
| 簡寫的首字母大寫形式的月名(英文 3 字符,本地化長度可變) |
| 簡寫的小寫形式的月名(英文 3 字符,本地化長度可變) |
| 月編號 (01–12) |
| 全大寫形式的日名(空格補齊到 9 字符) |
| 全首字母大寫形式的日名(空格補齊到 9 字符) |
| 全小寫形式的日名(空格補齊到 9 字符) |
| 簡寫的大寫形式的日名(英語 3 字符,本地化長度可變) |
| 簡寫的首字母大寫形式的日名(英語 3 字符,本地化長度可變) |
| 簡寫的小寫形式的日名(英語 3 字符,本地化長度可變) |
| 一年中的日(001–366) |
| ISO 8601 周編號方式的年中的日 (001–371; 年的第 1 日時第一個 ISO 周的周一) |
| 月中的日 (01–31) |
| 周中的日,周日 ( |
| 周中的 ISO 8601 日,周一 ( |
| 月中的周 (1–5) (第一周從該月的第一天開始) |
| 年中的周數 (1–53) (第一周從該年的第一天開始) |
| ISO 8601 周編號方式的年中的周數(01–53; 新的一年的第一個周四在第一周) |
| 世紀(2 位數)(21 世紀開始于 2001-01-01) |
| 儒略日(從午夜 UTC 的公元前 4714 年 11 月 24 日開始的整數日數) |
| 季度 |
| 大寫形式的羅馬計數法的月(I–XII; I=一月) |
| 小寫形式的羅馬計數法的月(i–xii; i=一月) |
| 大寫形式的時區縮寫(僅在 |
| 小寫形式的時區縮寫(僅在 |
| 時區的小時 |
| 時區的分鐘 |
| 從UTC開始的時區偏移(僅在 |
修飾語可以被應用于模板模式來修改它們的行為。例如,FMMonth
就是帶著FM
修飾語的Month
模式。用于日期/時間格式化的模板模式修飾語表展示了可用于日期/時間格式化的修飾語模式。
用于日期/時間格式化的模板模式修飾語
修飾語 | 描述 | 例子 |
| 填充模式(抑制前導零和填充的空格) |
|
| 大寫形式的序數后綴 |
|
| 小寫形式的序數后綴 |
|
| 固定的格式化全局選項(見使用須知) |
|
| 翻譯模式(基于lc_time使用本地化的日和月名) |
|
| 拼寫模式(未實現) |
|
日期/時間格式化的使用須知:
FM
抑制前導的零或尾隨的空白, 否則會把它們增加到輸入從而把一個模式的輸出變成固定寬度。在本數據庫中,FM
只修改下一個聲明,而在Oracle中,FM
影響所有隨后的聲明,并且重復的FM
修飾語將觸發填充模式開和關。無論是否指定
FM
,TM
抑制尾隨的空格。to_timestamp
和to_date
忽略輸入中的字母大小寫; 例如MON
,Mon
和mon
都接受相同的字符串。 當使用TM
修飾符時,大小寫折疊是根據函數的輸入排序規則進行的。to_timestamp
和to_date
跳過了輸入字符串開頭和日期和時間值周圍的多個空格,除非使用了FX
選項。 例如,to_to_timestamp(' 2000 JUN', 'YYY-MON')
和to_timestamp('2000 - JUN', 'YYY-MON')
都能工作,但to_timestamp('2000 JUN', 'FXYYYY-MON')
返回一個錯誤,因為to_timestamp
只期望一個空格。FX
必須指定為模板中的第一個項目。to_timestamp
和to_date
的模板字符串中的分隔符(一個空格或非字母/非數字字符)與輸入字符串中的任何一個分隔符相匹配,或者被跳過,除非使用了FX
選項。例如,to_to_timestamp('2000JUN', 'YYY///MON')
和to_timestamp('2000/JUN', 'YYY/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', 'YYY TZH')
與-10
匹配,但to_timestamp('2000 -10', 'YYYY TZH')
匹配10
到TZH
。在
to_char
模板里可以有普通文本,并且它們會被照字面輸出。你可以把一個子串放到雙引號里強迫它被解釋成一個文本,即使它里面包含模板模式也如此。例如,在'"Hello Year "YYYY'
中,YYYY
將被年份數據代替,但是Year
中單獨的Y
不會。在to_date
、to_number
以及to_timestamp
中,文本和雙引號字符串會導致跳過該字符串中所包含的字符數量,例如"XX"
會跳過兩個輸入字符(不管它們是不是XX
)。說明在本數據庫 12 之前,可以使用非字母或非數字字符跳過輸入字符串中的任意文本。例如,
to_timestamp('2000y6m1d', 'yyyyy-MM-DD')
以前是有效的。 現在,你只能使用字母字符來實現這個目的。 例如,to_timestamp(''2000y6m1d', 'yyyytMMtDDt')
和to_timestamp('2000y6m1d', 'yyyyy"y"MM"m"DD"d"')
跳過y
、m
和d
。如果你想在輸出里有雙引號,那么你必須在它們前面放反斜線,例如
'\"YYYY Month\"'
。不然,在雙引號字符串外面的反斜線就不是特殊的。在雙引號字符串內,反斜線會導致下一個字符被取其字面形式,不管它是什么字符(但是這沒有特殊效果,除非下一個字符是一個雙引號或者另一個反斜線)。在
to_timestamp
和to_date
中,如果年份格式聲明少于四位(如YYY
)并且提供的年份少于四位,年份將被調整為最接近于 2020 年,例如95
會變成 1995。在
to_timestamp
和to_date
中,負的年份被視為表示 BC。 如果你同時寫一個負的年份和一個顯式的BC
字段,你又會得到 AD。第 0 年的輸入被視為公元前 1 年。在
to_timestamp
和to_date
中,在處理超過 4 位數的年份時,YYYY
轉換具有限制。你必須在YYYY
后面使用一些非數字字符或者模板, 否則年份總是被解釋為 4 位數字。例如(對于 20000 年):to_date('200001131', 'YYYYMMDD')
將會被解釋成一個 4 位數字的年份,而不是在年份后使用一個非數字分隔符,像to_date('20000-1131', 'YYYY-MMDD')
或to_date('20000Nov31', 'YYYYMonDD')
。在
to_timestamp
和to_date
中,CC
(世紀)字段會被接受,但是如果有YYY
、YYYY
或者Y,YYY
字段則會忽略它。如果CC
與YY
或Y
一起使用,則結果被計算為指定世紀中的那一年。如果指定了世紀但是沒有指定年,則會假定為該世紀的第一年。在
to_timestamp
和to_date
中,工作日名稱或編號(DAY
、D
以及相關的字段類型)會被接受,但會為了計算結果的目的而忽略。季度(Q
)字段也是一樣。在
to_timestamp
和to_date
中,一個 ISO 8601 周編號的日期(與一個格里高利日期相區別)可以用兩種方法之一被指定為to_timestamp
和to_date
:年、周編號和工作日:例如
to_date('2006-42-4', 'IYYY-IW-ID')
返回日期2006-10-19
。如果你忽略工作日,它被假定為 1(周一)。年和一年中的日:例如
to_date('2006-291', 'IYYY-IDDD')
也返回2006-10-19
。
嘗試使用一個混合了 ISO 8601 周編號和格里高利日期的域來輸入一個日期是無意義的,并且將導致一個錯誤。在一個 ISO 周編號的年的環境下,一個“月”或“月中的日”的概念沒有意義。在一個格里高利年的環境下,ISO 周沒有意義。用戶應當避免混合格里高利和 ISO 日期聲明。
雖然to_date
將會拒絕混合使用格里高利和 ISO 周編號日期的域, to_char
卻不會,因為YYYY-MM-DD (IYYY-IDDD)
這種輸出格式也會有用。但是避免寫類似IYYY-MM-DD
的東西,那會得到在起始年附近令人驚訝的結果。
在
to_timestamp
中,毫秒(MS
)和微秒(US
)域都被用作小數點后的秒位。例如to_timestamp('12.3', 'SS.MS')
不是 3 毫秒, 而是 300,因為該轉換把它看做 12 + 0.3 秒。這意味著對于格式SS.MS
而言,輸入值12.3
、12.30
和12.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)
格式化HH
和HH12
為顯示在一個 12 小時的時鐘上,即零小時和 36 小時輸出為12
,而HH24
會輸出完整的小時值,對于間隔它可以超過23。
用于數字格式化的模板模式表展示了可以用于格式化數字值的模版模式。
用于數字格式化的模板模式
模式 | 描述 |
| 數位(如果無意義可以被刪除) |
| 數位(即便沒有意義也不會被刪除) |
| 小數點 |
| 分組(千)分隔符 |
| 尖括號內的負值 |
| 帶符號的數字(使用區域) |
| 貨幣符號(使用區域) |
| 小數點(使用區域) |
| 分組分隔符(使用區域) |
| 在指定位置的負號(如果數字 < 0) |
| 在指定位置的正號(如果數字 > 0) |
| 在指定位置的正/負號 |
| 羅馬數字(輸入在 1 和 3999 之間) |
| 序數后綴 |
| 移動指定位數(參閱注解) |
| 科學記數的指數 |
數字格式化的用法須知:
0
指定一個總是被打印的數位,即便它包含前導/拖尾的零。9
也指定一個數位,但是如果它是前導零則會被空格替換,而如果是拖尾零并且指定了填充模式則它會被刪除(對于to_number()
來說,這兩種模式字符等效)。模式字符
S
、L
、D
以及G
表示當前 locale 定義的負號、貨幣符號、小數點以及數字分隔符字符(見 lc_monetary 和 lc_numeric)。不管 locale 是什么,模式字符句號和逗號就表示小數點和數字分隔符。對于
to_char()
的模式中的一個負號,如果沒有明確的規定,將為該負號保留一列,并且它將被錨接到(出現在左邊)那個數字。如果S
正好出現在某個9
的左邊,它也將被錨接到那個數字。使用
SG
、PL
或MI
格式化的符號并不掛在數字上面; 例如,to_char(-12, 'MI9999')
生成'- 12'
,而to_char(-12, 'S9999')
生成' -12'
。(Oracle 里的實現不允許在9
前面使用MI
,而是要求9
在MI
前面。)TH
不會轉換小于零的數值,也不會轉換小數。PL
、SG
和TH
是本數據庫擴展。在
to_number
中,如果沒有使用L
或TH
之類的非數據模板模式,相應數量的輸入字符會被跳過,不管它們是否匹配模板模式,除非它們是數據字符(也就是數位、負號、小數點或者逗號)。例如,TH
會跳過兩個非數據字符。帶有
to_char
的V
會把輸入值乘上10^``n
,其中n
是跟在V
后面的位數。帶有to_number
的V
以類似的方式做除法。to_char
和to_number
不支持使用結合小數點的V
(例如,不允許99.9V99
)。EEEE
(科學記數法)不能和任何其他格式化模式或修飾語(數字和小數點模式除外)組合在一起使用,并且必須位于格式化字符串的最后(例如9.99EEEE
是一個合法的模式)。
某些修飾語可以被應用到任何模板來改變其行為。例如,FM99.99
是帶有FM
修飾語的99.99
模式。用于數字格式化的模板模式修飾語表中展示了用于數字格式化模式修飾語。
用于數字格式化的模板模式修飾語
修飾語 | 描述 | 例子 |
| 填充模式(抑制拖尾零和填充的空白) |
|
| 大寫序數后綴 |
|
| 小寫序數后綴 |
|
to_char 例子展示了一些使用to_char
函數的例子。
to_char
例子
表達式 | 結果 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|