插入时区夏令时

时间:2013-10-29 03:54:55

标签: sql postgresql datetime timezone dst

我想在包含时区的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'语法

2 个答案:

答案 0 :(得分:3)

正确的 方式根本不使用time with time zone(请注意timezone之间的空格),因为它被设计打破了。它符合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')