Vous avez affirmé que :
Alors vous jamais franchir la ligne de date dans la même ligne. Je suggère de sauvegarder 1x date
3x time
et le fuseau horaire (comme text
ou colonne 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
);
Comme vous l'avez déjà trouvé, timetz
(time with time zone
) devrait généralement être évitée
. Il ne peut pas gérer correctement les règles DST (d allumer des s en économisant t temps).
Donc essentiellement ce que vous aviez déjà . Déposez simplement le composant de date de start_hour
, c'est du fret mort. Diffuser timestamp
à time
pour couper la date. Comme :(timestamp '2018-03-25 1:00:00')::time
tz
peut être n'importe quelle chaîne acceptée par AT TIME ZONE
construire, mais pour gérer différents fuseaux horaires de manière fiable, il est préférable d'utiliser exclusivement des noms de fuseaux horaires. N'importe quel name
vous trouvez dans le catalogue système pg_timezone_names
.
Pour optimiser le stockage, vous pouvez collecter les noms de fuseaux horaires autorisés dans une petite table de recherche et remplacer le tz text
avec tz_id int REFERENCES my_tz_table
.
Deux exemples de lignes avec et sans 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
À des fins de représentation ou de calculs, vous pouvez faire des choses comme :
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;
Vous pouvez créer une ou plusieurs vues pour afficher facilement les chaînes selon les besoins. Le tableau sert à stocker les informations dont vous avez besoin .
Attention aux parenthèses ! Sinon l'opérateur +
se lierait avant AT TIME ZONE
en raison de la priorité des opérateurs
.
Et voici les résultats :
db<>violon ici
Étant donné que l'heure est manipulée à Vienne (comme n'importe quel endroit où s'appliquent des règles stupides d'heure d'été), vous obtenez des résultats "surprenants".
Connexe :
- Prise en compte de l'heure d'été dans Postgres, lors de la sélection d'éléments planifiés
- Ignorer l'heure zones dans Rails et PostgreSQL