Zapewniłeś, że:
Więc nigdy przekroczyć linię daty w tym samym wierszu. Proponuję zapisać 1x date
3x time
i strefa czasowa (jako text
lub kolumna 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
);
Jak już znalazłeś, timetz
(time with time zone
) należy generalnie unikać
. Nie radzi sobie poprawnie z regułami czasu letniego (d aylight s świerz t ime).
Więc w zasadzie to, co już miałeś . Po prostu upuść komponent daty z start_hour
, to martwy ładunek. Przesyłaj timestamp
do time
odciąć datę. Na przykład:(timestamp '2018-03-25 1:00:00')::time
tz
może być dowolnym ciągiem zaakceptowanym przez AT TIME ZONE
konstruować, ale aby niezawodnie radzić sobie z różnymi strefami czasowymi, najlepiej używać wyłącznie nazw stref czasowych. Dowolna name
znajdziesz w katalogu systemowym pg_timezone_names
.
Aby zoptymalizować pamięć, możesz zebrać dozwolone nazwy stref czasowych w małej tabeli wyszukiwania i zastąpić tz text
z tz_id int REFERENCES my_tz_table
.
Dwa przykładowe rzędy z i bez 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
Do celów reprezentacyjnych lub obliczeń możesz wykonać takie czynności, jak:
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;
Możesz utworzyć jeden lub więcej widoków aby łatwo wyświetlać ciągi w razie potrzeby. Tabela służy do przechowywania informacji, których potrzebujesz .
Zwróć uwagę na nawiasy! W przeciwnym razie operator +
powiąże się przed AT TIME ZONE
ze względu na pierwszeństwo operatorów
.
I spójrz na wyniki:
db<>fiddle tutaj
Ponieważ czas jest manipulowany w Wiedniu (jak w każdym miejscu, w którym obowiązują głupie zasady czasu letniego), otrzymujesz „zaskakujące” wyniki.
Powiązane:
- Uwzględnianie czasu letniego w Postgres podczas wybierania zaplanowanych elementów
- Ignorowanie czasu strefy łącznie w Railsach i PostgreSQL