Sie haben Folgendes behauptet:
Also niemals Überqueren Sie die Datumsgrenze innerhalb derselben Reihe. Ich schlage vor, 1x date
zu speichern 3x time
und die Zeitzone (als text
oder FK-Spalte):
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
);
Wie Sie bereits festgestellt haben, timetz
(time with time zone
) sollten generell vermieden werden
. Es kann nicht richtig mit DST-Regeln umgehen (d aylight s t Zeit).
Also im Grunde das, was Sie bereits hatten . Lassen Sie einfach die Datumskomponente von start_hour
weg , das ist tote Fracht. Cast timestamp
bis time
um das Datum abzuschneiden. Wie:(timestamp '2018-03-25 1:00:00')::time
tz
kann jede Zeichenfolge sein, die vom AT TIME ZONE
zu konstruieren, aber um zuverlässig mit unterschiedlichen Zeitzonen umzugehen, ist es am besten, ausschließlich Zeitzonennamen zu verwenden. Beliebiger name
finden Sie im Systemkatalog pg_timezone_names
.
Um die Speicherung zu optimieren, könnten Sie zulässige Zeitzonennamen in einer kleinen Nachschlagetabelle sammeln und tz text
ersetzen mit tz_id int REFERENCES my_tz_table
.
Zwei Beispielzeilen mit und ohne 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
Für Darstellungszwecke oder Berechnungen können Sie Dinge tun wie:
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;
Sie können eine oder mehrere Ansichten erstellen um Strings nach Bedarf einfach anzuzeigen. Die Tabelle dient zum Speichern der Informationen, die Sie benötigen .
Beachten Sie die Klammern! Sonst der Operator +
würde vor AT TIME ZONE
binden aufgrund von Operatorpriorität
.
Und sehen Sie sich die Ergebnisse an:
db<>fiddle hier
Da die Zeit in Wien manipuliert wird (wie überall dort, wo dumme DST-Regeln gelten), erhalten Sie "überraschende" Ergebnisse.
Verwandte:
- Berücksichtigung der Sommerzeit in Postgres bei der Auswahl geplanter Elemente
- Zeit ignorieren Zonen insgesamt in Rails und PostgreSQL