U beweerde dat:
Dus je nooit kruis de een datumlijn binnen dezelfde rij. Ik stel voor om 1x date
op te slaan 3x time
en de tijdzone (als text
of FK-kolom):
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
);
Zoals je al hebt gevonden, timetz
(time with time zone
) moet over het algemeen worden vermeden
. Het kan niet goed omgaan met de zomertijdregels (d aylight s aving t tijd).
Dus in feite wat je al had . Laat de datumcomponent gewoon vallen uit start_hour
, dat is dode vracht. Cast timestamp
tot time
om de datum af te snijden. Zoals:(timestamp '2018-03-25 1:00:00')::time
tz
kan elke tekenreeks zijn die wordt geaccepteerd door de AT TIME ZONE
constructie, maar om betrouwbaar met verschillende tijdzones om te gaan, kunt u het beste uitsluitend tijdzonenamen gebruiken. Elke name
vindt u in de systeemcatalogus pg_timezone_names
.
Om de opslag te optimaliseren, kunt u toegestane tijdzonenamen verzamelen in een kleine opzoektabel en tz text
vervangen met tz_id int REFERENCES my_tz_table
.
Twee voorbeeldrijen met en zonder 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
Voor representatiedoeleinden of berekeningen kunt u dingen doen als:
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;
U kunt een of meer weergaven maken om gemakkelijk strings weer te geven als dat nodig is. De tabel is voor het opslaan van de informatie die u nodig .
Let op de haakjes! Anders de operator +
zou binden vóór AT TIME ZONE
vanwege operatorvoorrang
.
En ziedaar de resultaten:
db<>fiddle hier
Omdat de tijd in Wenen wordt gemanipuleerd (zoals overal waar gekke zomertijdregels gelden), krijg je "verrassende" resultaten.
Gerelateerd:
- Rekening houden met DST in Postgres, bij het selecteren van geplande items
- Tijd negeren zones samen in Rails en PostgreSQL