本文介紹了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例子
運算式 | 結果 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|