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

Вземете време с часова зона от време без часова зона и името на часовата зона

ПРЕДУПРЕЖДЕНИЕ:PostgreSQL начинаещ (вижте коментарите по въпроса!). Все пак знам малко за часовите зони, така че знам какво има смисъл да попитам.

Струва ми се, че това е основно неподдържана ситуация (за съжаление), когато става въпрос за AT TIME ZONE . Разглеждане на AT TIME ZONE документация дава таблица, където типовете стойности "вход" са само:

  • клеймо без часова зона
  • клеймо с часова зона
  • час с часова зона

Липсва ни това, което искате:време без часова зона. Това, което питате, е донякъде логично, въпреки че зависи от датата... тъй като различните часови зони могат да имат различни отмествания в зависимост от датата. Например 12:00:00 Европа/Лондон май означава 12:00:00 UTC или може да означава 11:00:00 UTC, в зависимост от това дали е зима или лято.

В моята система, след като зададох системната часова зона на Америка/Реджина, заявката

SELECT ('2011-11-22T12:00:00'::TIMESTAMP WITHOUT TIME ZONE) 
                               AT TIME ZONE 'America/Vancouver'

дава ми 2011-11-22 14:00:00-06 като резултат. Това не е идеално , но поне дава моментален момент във времето (мисля). Вярвам, че ако извлечете това с клиентска библиотека - или го сравните с друг TIMESTAMP WITH TIME ZONE - ще получите правилния резултат. След това само преобразуването на текст използва системата часова зона за извеждане.

Ще бъде ли достатъчно добро за вас? Можете ли да промените своя SCHEDULES.time полето да бъде TIMESTAMP WITHOUT TIME ZONE поле или (по време на заявка) комбинирайте часа от полето с дата, за да създадете клеймо за време без часова зона?

РЕДАКТИРАНЕ:Ако сте доволни от "текущата дата", тя изглежда като можете просто да промените заявката си на:

SELECT (current_date + SCHEDULES.time) AT TIME ZONE USERS.tz
from SCHEDULES JOIN USERS on USERS.ID=SCHEDULES.USERID

Разбира се, текущата система датата може да не е същата като текущата дата в местната часова зона . Аз мисля това ще поправи тази част...

SELECT ((current_timestamp AT TIME ZONE USERS.tz)::DATE + schedules.time)
       AT TIME ZONE USERS.tz
from SCHEDULES JOIN USERS on USERS.ID=SCHEDULES.USERID

С други думи:

  • Вземете текущия момент
  • Разберете местната дата/час в часовата зона на потребителя
  • Вземете датата на това
  • Добавете графика към тази дата, за да получите TIMESTAMP WITHOUT TIME ZONE
  • Използвайте AT TIME ZONE за да приложите часовата зона към тази местна дата/час

Сигурен съм, че има по-добър начин, но мисля има смисъл.

Трябва да знаете, че в някои случаи това може да се провали:

  • Какъв искате да бъде резултатът за време от 01:30 в ден, когато часовникът прескача от 01:00 до 02:00, така че 01:30 изобщо не се появява?
  • Какъв искате да бъде резултатът за време от 01:30 в ден, когато часовникът се върне от 02:00 до 01:00, така че 01:30 се появява два пъти?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. pg_dump с --exclude-table все още включва тези таблици във фоновите команди COPY, които изпълнява?

  2. Създайте уникален индекс на неуникална колона

  3. Заявка за транспониране на кръстосана таблица

  4. postgreSQL.app :създаване на база данни

  5. Попълване на многомерен масив