PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Gestisci correttamente TIME WITH TIME ZONE in PostgreSQL

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: