你声称:
“每个时间”列表示中指定的一天中的一个时刻
REPORT_DATE
。
所以你
从不
跨同一行内的a日期行。我建议保存1x
date
3倍
time
以及
时区
(作为
text
或FK列):
CREATE TABLE legacy_table (
event_id bigint PRIMARY KEY NOT NULL
, report_date date NOT NULL
, start_hour time
, end_hour time
, expected_hour time
, tz text -- time zone
);
就像你已经发现的那样,
timetz
(
time with time zone
) should generally be avoided
。无法正确处理DST规则(
D
aylight公司
s
aving公司
T
输入法)。
所以
基本上是你已经拥有的
.只需从中删除日期组件
start_hour
,那是空车。铸造
timestamp
到
时间
取消日期。例如:
(timestamp '2018-03-25 1:00:00')::time
tz
可以是
AT TIME ZONE
构造,但要可靠地处理不同的时区,最好只使用时区名称。任何
name
您可以在
system catalog
pg_timezone_names
。
为了优化存储,您可以在一个小的查找表中收集允许的时区名称并替换
tz text
具有
tz_id int REFERENCES my_tz_table
。
带和不带DST的两个示例行:
INSERT INTO legacy_table VALUES
(1, '2018-03-25', '1:00', '3:00', '2:00', 'Europe/Vienna') -- sadly, with DST
, (2, '2018-03-25', '1:00', '3:00', '2:00', 'Europe/Moscow'); -- Russians got rid of DST
出于表示或计算目的,您可以执行以下操作:
SELECT (report_date + start_hour) AT TIME ZONE tz AT TIME ZONE 'UTC' AS start_utc
, (report_date + end_hour) AT TIME ZONE tz AT TIME ZONE 'UTC' AS end_utc
, (report_date + expected_hour) AT TIME ZONE tz AT TIME ZONE 'UTC' AS expected_utc
-- START_HOUR - END_HOUR
, (report_date + start_hour) AT TIME ZONE tz
- (report_date + end_hour) AT TIME ZONE tz AS start_minus_end
FROM legacy_table;
您可以创建一个或多个
views
根据需要随时显示字符串。该表用于存储您需要的信息
需要
。
注意括号!否则操作员
+
将在之前绑定
在时区
由于
operator precedence
。
看看结果:
数据库(&L)&燃气轮机;不停摆弄
here
由于时间在维也纳被操纵(就像任何愚蠢的DST规则适用的地方一样),你会得到“令人惊讶”的结果。
相关: