本文介紹了PolarDB PostgreSQL版(兼容Oracle)支持的日期類型。

說明 在下面關于日期類型的討論中,假設無論什么時候創建或修改一張表,配置參數polar_comp_redwood_date都已設定為true
名稱存儲大小描述最小值最大值精度
DATE8 bytes日期和時間。4713 BC5874897 AD1 秒
INTERVAL DAY TO SECOND [(p)]12 bytes帶設定精度的時間段。-178000000 年178000000 年1 微秒/14 位
INTERVAL YEAR TO MONTH12 bytes時間段。-178000000 年178000000 年1 微秒/14 位
TIMESTAMP [(p)]8 bytes日期和時間的時間戳。4713 BC5874897 AD1 微秒
TIMESTAMP [(p)] WITH TIME ZONE8 bytes帶時區的日期和時間的時間戳。4713 BC5874897 AD1 微秒
TIME [(p)]8 bytes只用于一日內的時間。00:00:0024:00:001 毫秒/14 位
TIME [(p)] WITH TIME ZONE12 bytes帶時區的只用于一日內的時間。00:00:00+145924:00:00-14591 毫秒/14 位

當關鍵字DATE作為列的數據類型在數據定義語言(DDL)命令,如CREATE TABLE或者ALTER TABLE命令中出現的時候,在把數據表定義存儲在數據庫時,會自動把它轉換成TIMESTAMP(0)類型。因此在日期中帶有的時間部分也會隨著存儲在列中。

當關鍵字DATE作為變量的數據類型在SPL程序的聲明部分出現,或者作為SPL存儲過程或SPL函數中形參的數據類型出現,或者作為一個SPL函數返回值類型出現的時候,總是被轉換成TIMESTAMP(0)類型,因此它可以處理出現的時間部分值。

我們可以在TIMESTAMP類型的值上指定一個代表精度的值p,用來指定在秒字段中能夠保留的小數位數。參數p的取值范圍在0到6之間,缺省值是6。

當TIMESTAMP值以雙精度浮點類型值存儲的時候(當前是缺省設置),實際精度值的限制可以小于6。在2000-01-01午夜之前或者之后的TIMESTAMP類型值是以秒為單位來存儲的。而從日期為2000-01-01向后的幾年內,毫秒精度是可以實現的,但是隨著日期的延續,精度值就不會這么準確了。當TIMESTAMP值以8字節整數(這是一個編譯時的選項)的形式存儲的時候,對于所有級別的時間值來說,毫秒級的精度都是有效的。但是8字節整數的TIMESTAMP類型值的日期范圍比上面所示的要小些。它的范圍是從公元前4713年到公元294276年。

TIMESTAMP (p) WITH TIME ZONE類似于TIMESTAMP (p),但是它也包括時區。

INTERVAL 類型

INTERVAL值指定了一個時間段。類型INTERVAL的值由描述數據值的字段組成。下列表中的字段允許出現在INTERVAL類型中。

字段名取值
YEAR整數值(正或負)。
MONTH0到11。
DAY整數值(正或負)。
HOUR0到23。
MINUTE0到59。
SECOND0到59.9(p),其中9(p)是分數秒的精度。

這些字段必須以降序的形式呈現,從YEARS到MONTHS,從DAYS到HOURS,從MINUTES再到SECONDS。

PolarDB支持兩種與Oracle兼容的INTERVAL類型。

  • PolarDB支持的第一種變量為INTERVAL DAY TO SECOND [(p)]。這種變量可存儲天、小時、分鐘和秒的時間間隔。
    說明 p用于指定second字段的精度。
    PolarDB將下面的值解釋為:
    • INTERVAL '1 2:34:5.678' DAY TO SECOND(3)

      1天、2小時、34分鐘、5秒和678/1000秒。

    • INTERVAL '1 23' DAY TO HOUR

      1天和23小時。

    • INTERVAL '2:34' HOUR TO MINUTE

      2小時和34分鐘。

    • INTERVAL '2:34:56.129' HOUR TO SECOND(2)
      2小時、34分鐘、56秒和13/1000秒。
      說明 因為指定了精度,所以小數點后一位的數四舍五入,從而變為13。
  • PolarDB支持的第二種與Oracle兼容的變量為INTERVAL YEAR TO MONTH。這種變量可以存儲年和月的時間間隔。
    PolarDB將下面的值解釋為:
    • INTERVAL '12-3' YEAR TO MONTH

      12年和3個月。

    • INTERVAL '45' YEAR

      45年。

    • INTERVAL '300' MONTH

      25年。

日期和時間的輸入

日期和時間輸入值一般格式是ISO 8601 SQL兼容格式,Oracle缺省的dd-MON-yy格式,以及其他的一些對年月日有明確的區分的格式。然而避免在格式上出現不明確的最好方法是使用函數TO_DATE。

任何日期或者時間輸入值都需要像文本字符串那樣用單引號引起來,我們可以使用下面這種SQL標準語法。
type 'value' type
說明
  • type可以是日期類型,也可以是TIMESTAMP類型。
  • value是內容為日期/時間的字符串。
  • 日期
    下面列出了一些允許使用的日期輸入格式,所有這些格式的值都等同于1999年1月8號。
    • January 8, 1999
    • 1999-01-08
    • 1999-Jan-08
    • Jan-08-1999
    • 08-Jan-1999
    • 08-Jan-99
    • Jan-08-99
    • 19990108
    • 990108

    我們可以把日期類型值分配給數據類型為DATE或者TIMESTAMP的列或者變量。如果日期類型的值不附帶時間類型值,那么小時,分鐘和秒數的字段值都是零。

  • 時間
    在下面的表中顯示了一些日期或者時間截類型值中帶有時間部分的示例。
    示例描述
    04:05:06.789ISO 8601
    04:05:06ISO 8601
    04:05ISO 8601
    040506ISO 8601
    04:05 AM與04:05相同,AM不影響數值。
    04:05 PM與16:05相同,輸入小時數必須小于等于12。
    04:05:06.789-8ISO 8601
    04:05:06-08:00ISO 8601
    04:05-08:00ISO 8601
    040506-08ISO 8601
    04:05:06 PST縮寫的時區。
    2003-04-12 04:05:06America/New_York用名稱聲明的時區。
  • 時間截

    一個有效的時間戳類型輸入值是由一個日期和一個時間類型值組成。時間戳中日期部分能夠根Table 3-3-6 Date Input顯示的示例進行格式化。時間戳中的時間部分可以根據顯示的示例進行格式化。

    下面這個關于時間戳的示例,使用了Oracle的缺省格式。

    08-JAN-99 04:05:06

    下面這個關于時間戳的示例,遵循了ISO8601標準的格式。

    1999-01-08 04:05:06

日期和時間的輸出

日期和時間類型的缺省輸出格式既可以是與Oracle兼容,被稱為Redwood日期的格式(dd-MON-yy),也可以是根據數據庫程序接口而決定的ISO8601格式(yyyy-mm-dd)。使用JDBC進行SQL交互的程序是以ISO8601格式顯示日期。其他程序例如PSQL以Redwood格式來顯示日期。

在下面的表中顯示了關于Redwood和ISO8601這兩種風格輸出格式的示例。
格式示例
Redwood style31-DEC-05 07:37:16
ISO 8601/SQL standard1997-12-17 07:37:16

內部格式

對于所有的日期和時間計算,PolarDB都是使用Julian日期進行的。在每年長度為365.2425天的這個假設基礎上,Julian日期能夠正確的預測和計算從公元前4713年開始之后的任意日期。