Hai affermato che:
Quindi tu mai attraversare la linea della data all'interno della stessa riga. Suggerisco di salvare 1x date
3x time
e il fuso orario (come text
o colonna 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
);
Come hai già trovato, timetz
(time with time zone
) dovrebbe essere generalmente evitato
. Non può gestire correttamente le regole dell'ora legale (d aylight s avendo t ora).
Quindi fondamentalmente quello che avevi già . Rilascia il componente data da start_hour
, questo è un carico morto. Trasmetti timestamp
a time
per tagliare la data. Come:(timestamp '2018-03-25 1:00:00')::time
tz
può essere qualsiasi stringa accettata da AT TIME ZONE
build, ma per gestire in modo affidabile fusi orari diversi, è meglio utilizzare esclusivamente i nomi dei fusi orari. Qualsiasi name
si trova nel catalogo di sistema pg_timezone_names
.
Per ottimizzare l'archiviazione, puoi raccogliere i nomi dei fusi orari consentiti in una piccola tabella di ricerca e sostituire tz text
con tz_id int REFERENCES my_tz_table
.
Due righe di esempio con e senza ora legale:
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
Per scopi di rappresentazione o calcoli puoi fare cose come:
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;
Potresti creare una o più visualizzazioni per visualizzare prontamente le stringhe secondo necessità. La tabella serve per memorizzare le informazioni di cui hai bisogno .
Nota le parentesi! Altrimenti l'operatore +
si legherebbe prima di AT TIME ZONE
a causa della precedenza dell'operatore
.
Ed ecco i risultati:
db<>violino qui
Dal momento che l'ora è manipolata a Vienna (come qualsiasi luogo in cui si applicano le stupide regole dell'ora legale), ottieni risultati "sorprendenti".
Correlati:
- Contabilità dell'ora legale in Postgres, quando si selezionano gli elementi programmati
- Ignorando il tempo zone del tutto in Rails e PostgreSQL