Вие твърдите, че:
Така че вие никога пресечете линията за дата в рамките на същия ред. Предлагам да запазите 1x date
3x time
и часовата зона (като text
или 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
);
Както вече открихте, timetz
(time with time zone
) обикновено трябва да се избягва
. Не може да работи правилно с правилата за DST (d айлайтната авингта име).
И така в общи линии това, което вече имате . Просто изпуснете компонента за дата от start_hour
, това е мъртъв товар. Предаване на timestamp
до time
да отрежете датата. Като:(timestamp '2018-03-25 1:00:00')::time
tz
може да бъде всеки низ, приет от AT TIME ZONE
construct, но за да работите надеждно с различни часови зони, най-добре е да използвате изключително имена на часови зони. Всяко name
намирате в системен каталог pg_timezone_names
.
За да оптимизирате съхранението, можете да съберете разрешените имена на часови зони в малка справочна таблица и да замените tz text
с tz_id int REFERENCES my_tz_table
.
Два примерни реда със и без 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
За представителни цели или изчисления можете да правите неща като:
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;
Може да създадете един или повече изгледи за лесно показване на низове, ако е необходимо. Таблицата е за съхраняване на информацията, от която се нуждаете .
Обърнете внимание на скобите! В противен случай операторът +
ще се обвърже преди AT TIME ZONE
поради предимство на оператор
.
И вижте резултатите:
db<>fiddle тук
Тъй като във Виена времето се манипулира (като всяко място, където се прилагат глупави правила за лятно часово време), получавате „изненадващи“ резултати.
Свързани:
- Отчитане на лятното часово време в Postgres при избиране на планирани елементи
- Игнориране на времето зони изцяло в Rails и PostgreSQL