Du hævdede, at:
Så du aldrig krydse a-datolinjen i samme række. Jeg foreslår at gemme 1x date
3x time
og tidszonen (som text
eller FK kolonne):
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
);
Som du allerede har fundet, timetz
(time with time zone
) bør generelt undgås
. Det kan ikke håndtere sommertidsregler korrekt (d aylight s aving t ime).
Så dybest set hvad du allerede havde . Bare slip datokomponenten fra start_hour
, det er dødfragt. Cast timestamp
til time
at skære datoen af. Like:(timestamp '2018-03-25 1:00:00')::time
tz
kan være en hvilken som helst streng, der accepteres af AT TIME ZONE
konstruere, men for at håndtere forskellige tidszoner pålideligt, er det bedst udelukkende at bruge tidszonenavne. Ethvert name
du finder i systemkataloget pg_timezone_names
.
For at optimere lagringen kan du samle tilladte tidszonenavne i en lille opslagstabel og erstatte tz text
med tz_id int REFERENCES my_tz_table
.
To eksempler på rækker med og uden sommertid:
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
Til repræsentationsformål eller beregninger kan du gøre ting som:
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;
Du kan muligvis oprette en eller flere visninger for nemt at vise strenge efter behov. Tabellen er til lagring af de oplysninger, du bruger for .
Bemærk parentesen! Ellers operatoren +
ville binde før AT TIME ZONE
på grund af operatørprioritet
.
Og se resultaterne:
db<>fiddle her
Da tiden er manipuleret i Wien (som alle steder, hvor dumme sommertidsregler gælder), får du "overraskende" resultater.
Relateret:
- Regnskab for sommertid i Postgres, ved valg af planlagte varer
- Ignorerer tid zoner helt i Rails og PostgreSQL