我想在包含时区的postgresql中插入时间数据类型,并且知道夏令时。这就是我所做的:
CREATE TABLE mytable(
...
start_time time(0) with time zone,
end_time time(0) with time zone
)
INSERT INTO mytable(start_time, end_time)
VALUES(TIME '08:00:00 MST7MDT', TIME '18:00:00 MST7MDT')
我收到以下错误:
类型时间的输入语法无效:“08:00:00 MST7MDT”
如果我使用'MST'而不是'MST7MDT',它会起作用,但我需要它知道DST。我也尝试使用'America / Edmonton'作为时区,但我得到了同样的错误。
使用时区和DST插入时间值(不是时间戳)的正确方法是什么?
编辑: 我实际上想使用'America / Edmonton'语法
答案 0 :(得分:3)
正确的 方式根本不使用time with time zone
(请注意time
和zone
之间的空格),因为它被设计打破了。它符合SQL标准,因此Postgres支持该类型 - 但建议不使用它。更多相关答案:
Accounting for DST in Postgres, when selecting scheduled items
由于您遇到DST问题,timetz
(短名称)是一个特别糟糕的选择。它没有能力处理夏令时。无法判断8:00:00
是在冬季还是夏季。
请改用timestamp with time zone
(timstamptz
)。您始终可以丢弃日期部分。只需使用start_time::time
即可从timestamptz
获取本地时间。或使用AT TIME ZONE
转置到您的时区。
通常,要自动将DST考虑在内,请使用 时区名称 而不是时区缩写。在此相关问题中的更多解释&答案:
Time zone names with identical properties yield different result when applied to timestamp
在您的特定情况下,您可以使用America/Los_Angeles
(例如timestamptz
):
INSERT INTO mytable(start_time, end_time)
VALUES('1970-01-01 08:00:00 America/Los_Angeles'
, '1970-01-01 18:00:00 America/Los_Angeles')
我通过检查找到了这个:
SELECT * FROM pg_timezone_names
WHERE utc_offset = '-07:00'
AND is_dst;
关于时区处理的基础知识:
Ignoring timezones altogether in Rails and PostgreSQL
答案 1 :(得分:0)
这个怎么样?
INSERT INTO mytable(start_time, end_time)
VALUES('08:00:00'::time at time zone 'MST7MDT', '18:00:00'::time at time zone 'MST7MDT')