CodeGym /课程 /SQL SELF /处理日期和时间时的常见错误

处理日期和时间时的常见错误

SQL SELF
第 32 级 , 课程 4
可用

今天我们又来聊聊错误。因为搞日期和时间就像踩地雷:一切都好,直到你第一步踩错。

选数据类型时的错误

这通常就是一切悲剧的开始。选错数据类型,之前你对日期和时间的努力都白费了。

场景 1:用 DATE 代替 TIMESTAMP

当你记录一个既有日期又有时间的事件时,只用 DATE,你就会丢掉重要信息。

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

这样设计的话,你根本不知道两个订单是早上下的还是晚上下的。为啥要放弃喝咖啡时欣赏漂亮时间戳的机会呢?

场景 2:忘了时区

如果你的应用有国际用户,但你只用 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:减 interval 时写乱了

加减 interval 时要小心:

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

多测试你的 SQL。 一定要确认结果和你预期一样,特别是 interval、格式和四舍五入相关的。

用 UTC 存时间数据。 这样能最大程度避免时区混乱。

检查格式。 TO_CHAR()TO_DATE() 的格式一定要和你的数据匹配。

小心用各种函数。 认真看看 PostgreSQL 时间函数文档,别被坑了。

搞时间数据确实挺麻烦,但只要你方法对、细节注意到,绝对能顺利搞定。日期和时间是你应用里很重要的一部分,忘了它们就像忘了周一早上定闹钟一样危险!

1
调查/小测验
处理时区第 32 级,课程 4
不可用
处理时区
处理时区
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION