CodeGym /課程 /SQL SELF /處理日期與時間時常見的錯誤

處理日期與時間時常見的錯誤

SQL SELF
等級 32 , 課堂 4
開放

今天我們又要來聊聊錯誤了。因為搞日期跟時間,根本就像在踩地雷:一切都很順,直到你第一步踩錯。

選資料型別時的錯誤

這裡常常就是災難的開端。選錯資料型別,會讓你之前處理日期和時間的努力全白費。

情境 1: 用 DATE 取代 TIMESTAMP

如果你記錄的事件不只有日期,還有時間,結果只用 DATE,那你就會遺失重要資訊啦。

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    order_date DATE -- 只有日期
);

這樣設計,你根本不知道兩個訂單是早上還是晚上下的。何必放棄喝咖啡時欣賞漂亮 timestamp 的機會呢?

情境 2: 忘記時區

如果你的 app 有國際用戶,但你只用 TIMESTAMP 存日期和時間,沒考慮時區,那你的資料就會變成「無家可歸」。TIMESTAMPTZ 幫你解決這個問題。

CREATE TABLE events (
    event_time TIMESTAMP -- 沒有時區
);

沒人想把紐約的晚上活動搞成東京的早上吧。用 TIMESTAMPTZ 才對!

用函式時的錯誤

情境 1: TO_CHAR() 格式寫錯

如果你格式寫錯,問題就來了。例如:

SELECT TO_CHAR(NOW(), 'YYYY-DD-MM'); -- 哎呀,月跟日寫反了

這裡你本來想要 年-月-日,結果變成 年-日-月。這會讓用戶遇到很搞笑(但不一定開心)的狀況。格式一定要檢查清楚。

情境 2: 用 TO_DATE() 時出錯

反過來,如果你想把字串轉成日期,但格式不對,PostgreSQL 會直接報錯。

SELECT TO_DATE('10/31/2023', 'YYYY-MM-DD'); -- 錯誤!格式不符。

字串格式一定要跟你指定的完全一樣。例如:

SELECT TO_DATE('2023-10-31', 'YYYY-MM-DD'); -- 這樣才對。

處理時間區間時的錯誤

情境 1: 隱式型別轉換

有時候你會忘記型別轉換的細節。例如:

SELECT NOW() + '1'; -- 錯誤!'1' 是啥?

PostgreSQL 不知道你想加一天。正確寫法:

SELECT NOW() + INTERVAL '1 day';

情境 2: 區間減法搞混

加減區間時要小心:

SELECT NOW() - INTERVAL '-1 day'; -- 這其實是加一天!

這裡雙負號反而變成加。這種寫法最好別用。

四捨五入和截斷資料時的錯誤

情境 1: DATE_TRUNC() 截錯

DATE_TRUNC() 做資料分組時,一定要確認你選對層級。例如:

SELECT DATE_TRUNC('hour', NOW()); -- 截到整點
SELECT DATE_TRUNC('minute', NOW()); -- 截到整分鐘

如果你預期一個結果,卻拿到另一個,可能就是層級選錯了。

情境 2: DATE_TRUNC() 忘記時區

如果你處理不同時區的時間,結果可能會很意外:

SELECT DATE_TRUNC('day', NOW() AT TIME ZONE 'UTC');

一定要確認時區設對,不然真的會「迷失在時間裡」!

Unix 時間:消失的秒數

Unix 時間(EPOCH)很方便,但也很陰險。最常見的錯誤就是把秒跟毫秒搞混。

SELECT TO_TIMESTAMP(1680000000); -- 這樣對(秒)。
SELECT TO_TIMESTAMP(1680000000000); -- 這樣錯!太多零了。

一定要確認你的 timestamp 單位,不然會多存一大堆多餘的秒數。

時區相關的錯誤

情境 1: 時區搞混

如果你有來自不同時區的用戶,資料很容易混在一起。例如:

SELECT TIMESTAMP '2023-10-01 10:00:00' AT TIME ZONE 'UTC';

一定要搞清楚你的資料到底是哪個時區。

情境 2: 時區重複計算

把日期時間存進去後又再處理時區,這樣很糟:

SELECT TIMESTAMP '2023-10-01 10:00:00 UTC' AT TIME ZONE 'UTC'; -- 千萬別這樣!

這會讓你的計算全錯。

避免錯誤的建議

選對資料型別。 如果你要處理國際時間,請用 TIMESTAMPTZ。只要日期就用 DATE

多測試你的查詢。 一定要確認結果跟你預期一樣,尤其是處理區間、格式或四捨五入時。

用 UTC 存時間。 這是避免時區混亂的最佳做法。

檢查格式。 TO_CHAR()TO_DATE() 的格式一定要跟你的資料一致。

小心用函式。 仔細看 PostgreSQL 時間函式文件,才不會被嚇到。

處理時間資料真的不簡單,但只要方法對、細節顧好,一切都會很順。日期和時間是你 app 的重要一環,忘了它們就像週一早上忘記設鬧鐘一樣危險!

1
問卷/小測驗
時區操作,等級 32,課堂 4
未開放
時區操作
時區操作
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION