PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Правилно обработване на TIME WITH TIME ZONE в PostgreSQL

Вие твърдите, че:

Така че вие ​​никога пресечете линията за дата в рамките на същия ред. Предлагам да запазите 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 тук

Тъй като във Виена времето се манипулира (като всяко място, където се прилагат глупави правила за лятно часово време), получавате „изненадващи“ резултати.

Свързани:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Прехвърляне на тип данни на Postgres

  2. hibernate не можа да получи следващата стойност на последователността

  3. Настройка и използване на pgmemcache

  4. Не може да се свърже с отдалечена база данни на Heroku Postgres с помощта на Play Framework 2.2.2

  5. Как да вмъкна стойност в оператор select с помощта на JavaScript, по-специално когато използвам express и postgres?