-- 使用特殊表 SYSIBM.SYSDUMMY1
SELECT CURRENT DATE FROM SYSIBM.SYSDUMMY1;
SELECT CURRENT TIME FROM SYSIBM.SYSDUMMY1;
SELECT CURRENT TIMESTAMP FROM SYSIBM.SYSDUMMY1;
-- 或使用 VALUES 子句(CLP 環境)
VALUES CURRENT DATE;
VALUES CURRENT TIME;
VALUES CURRENT TIMESTAMP;
-- 轉換為 UTC/GMT
CURRENT TIME - CURRENT TIMEZONE;
CURRENT TIMESTAMP - CURRENT TIMEZONE;
| 函數 | 範例 | 回傳 |
|---|---|---|
| YEAR | YEAR(CURRENT TIMESTAMP) | 年份 (四位數) |
| MONTH | MONTH(CURRENT TIMESTAMP) | 月份 (1-12) |
| DAY | DAY(CURRENT TIMESTAMP) | 日期 (1-31) |
| HOUR | HOUR(CURRENT TIMESTAMP) | 小時 (0-23) |
| MINUTE | MINUTE(CURRENT TIMESTAMP) | 分鐘 (0-59) |
| SECOND | SECOND(CURRENT TIMESTAMP) | 秒 (0-59) |
| MICROSECOND | MICROSECOND(CURRENT TIMESTAMP) | 微秒 (0-999999) |
-- 日期運算
CURRENT DATE + 1 YEAR
CURRENT DATE + 3 YEARS + 2 MONTHS + 15 DAYS
-- 時間運算
CURRENT TIME + 5 HOURS - 3 MINUTES + 10 SECONDS
-- 計算兩日期相差天數
DAYS(CURRENT DATE) - DAYS(DATE('1999-10-22'))
-- 將 timestamp 微秒歸零
CURRENT TIMESTAMP - MICROSECOND(CURRENT TIMESTAMP) MICROSECONDS
CHAR(CURRENT DATE) -- 依資料庫地區碼格式
CHAR(CURRENT TIME)
CHAR(CURRENT TIMESTAMP)
-- 指定格式(需綁定特定套件)
-- 參考「改變日期格式」一節
TIMESTAMP('2002-10-20-12.00.00.000000')
TIMESTAMP('2002-10-20 12:00:00')
DATE('2002-10-20')
DATE('10/20/2002')
TIME('12:00:00')
TIME('12.00.00')
SELECT DATE(2001-09-22) FROM SYSIBM.SYSDUMMY1;
-- 結果:05/24/0006 (相差近 2000 年!)
-- 原因:無引號視為數值運算 2001-9-22 = 1970
-- DATE(1970) 解釋為「西元元年 + 1970 天」
-- 正確寫法:
SELECT DATE('2001-09-22') FROM SYSIBM.SYSDUMMY1;
| 函數 | 說明 |
|---|---|
| DAYNAME | 星期名稱 (如 Friday) |
| DAYOFWEEK | 星期幾 (1=週日..7=週六) |
| DAYOFWEEK_ISO | ISO 週幾 (1=週一..7=週日) |
| DAYOFYEAR | 一年中的第幾天 (1-366) |
| DAYS | 日期轉整數 (西元元年起算天數) |
| JULIAN_DAY | 儒略日數 |
| MIDNIGHT_SECONDS | 午夜起秒數 (0-86400) |
| MONTHNAME | 月份名稱 (如 January) |
| TIMESTAMP_ISO | 依日期/時間/時間戳回傳 ISO 時間戳 |
| TIMESTAMP_FORMAT | 依樣板解析字串回傳時間戳 |
| TIMESTAMPDIFF | 兩時間戳差異估算值(不精確) |
| TO_CHAR / VARCHAR_FORMAT | 依樣板格式化時間戳為字串 |
| TO_DATE / TIMESTAMP_FORMAT | 依樣板解析字串為時間戳 |
| WEEK | 一年中的第幾週 (1-54, 週日為首) |
| WEEK_ISO | ISO 週數 (1-53) |
格式由建庫時 territory 參數決定。可透過重新綁定套件變更:
# Windows
cd C:\Program Files\IBM\SQLLIB\BND
db2 connect to MYDB
db2 bind @db2ubind.lst DATETIME ISO BLOCKING ALL GRANT PUBLIC
# Linux/UNIX
cd /home/db2inst1/sqllib/bnd
db2 connect to MYDB
db2 bind @db2ubind.lst DATETIME ISO BLOCKING ALL GRANT PUBLIC
支援格式:DEF(地區預設)、EUR、ISO (YYYY-MM-DD)、JIS、LOC、USA。
需求:輸出 YYYYMMDD、MM/DD/YYYY 等非標準格式。
CREATE FUNCTION TS_FMT(TS TIMESTAMP, FMT VARCHAR(20))
RETURNS VARCHAR(50)
LANGUAGE SQL
DETERMINISTIC
NO EXTERNAL ACTION
RETURN
WITH TMP (DD, MM, YYYY, HH, MI, SS, NNNNNN) AS (
SELECT
SUBSTR(DIGITS(DAY(TS)), 9),
SUBSTR(DIGITS(MONTH(TS)), 9),
RTRIM(CHAR(YEAR(TS))),
SUBSTR(DIGITS(HOUR(TS)), 9),
SUBSTR(DIGITS(MINUTE(TS)), 9),
SUBSTR(DIGITS(SECOND(TS)), 9),
RTRIM(CHAR(MICROSECOND(TS)))
FROM SYSIBM.SYSDUMMY1
)
SELECT CASE FMT
WHEN 'YYYYMMDD' THEN YYYY || MM || DD
WHEN 'MMDDYYYY' THEN MM || DD || YYYY
WHEN 'YYYY/MM/DD HH:MI:SS' THEN YYYY || '/' || MM || '/' || DD || ' ' || HH || ':' || MI || ':' || SS
WHEN 'NNNNNN' THEN NNNNNN
ELSE 'FORMAT ' || COALESCE(FMT, 'NULL') || ' NOT RECOGNIZED'
END
FROM TMP;
VALUES TS_FMT(CURRENT TIMESTAMP, 'YYYYMMDD'); -- 20230818
VALUES TS_FMT(CURRENT TIMESTAMP, 'MMDDYYYY'); -- 08182023
VALUES TS_FMT(CURRENT TIMESTAMP, 'INVALID'); -- FORMAT INVALID NOT RECOGNIZED
TIMESTAMPDIFF 估算不精確(假設每月 30 天)。精確秒差:
(DAYS(T1) - DAYS(T2)) * 86400 + (MIDNIGHT_SECONDS(T1) - MIDNIGHT_SECONDS(T2))
-- 建立 UDF 方便重用
CREATE FUNCTION SECONDS_DIFF(T1 TIMESTAMP, T2 TIMESTAMP)
RETURNS INTEGER
RETURN (DAYS(T1) - DAYS(T2)) * 86400 + (MIDNIGHT_SECONDS(T1) - MIDNIGHT_SECONDS(T2));
CREATE FUNCTION DAYS_IN_YEAR(YR INTEGER)
RETURNS INTEGER
RETURN CASE MOD(YR, 400)
WHEN 0 THEN 366
ELSE CASE MOD(YR, 4)
WHEN 0 THEN CASE MOD(YR, 100)
WHEN 0 THEN 365 ELSE 366 END
ELSE 365 END
END;
DB2 日期時間功能強大且符合 SQL 標準,善用內建函數、自然語言運算、自訂 UDF,能優雅解決各類時間計算需求。