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

Knex безшумно преобразува времевите марки на Postgres с часова зона и връща неправилно време

Вероятно нещата се провалят, защото когато правите заявки за дати и часове от база данни в определена часова зона и ефективно преобразувате типа на времевия печат да бъде времеви печат без часова зона. В този случай базата данни няма да изпрати информация на knex за това в коя часова зона е върнатото време.

Така че knex (или по-скоро pg драйвер, който knex използва) интерпретира вашето времево клеймо като местно време, което зависи от настройката на часовата зона на вашия сървър на приложения, изпълняващ knex.

Можете да извлечете времето точно като UTC и да извършите преобразуване на часовата зона в страната на JavaScript с библиотеки moment или luxon (последната IMO е по-добра за обработка на часовата зона).

Друго решение би било да се каже на драйвера на pg, че времевият печат и часовият печат с типове часови зони не трябва да се преобразуват в JavaScript Date обекти.

Може да се направи по следния начин (https://github.com/brianc/node-pg- типове ):

const types = require('pg').types;
const TIMESTAMPTZ_OID = 1184;
const TIMESTAMP_OID = 1114;
types.setTypeParser(TIMESTAMPTZ_OID, val => val);
types.setTypeParser(TIMESTAMP_OID, val => val);

Този код, който кара всички времеви клейма да се връщат като низове, може да се добави например в началото на knexfile.js . Тези върнати низове ще бъдат точно в същия формат, в който са били върнати от самия сървър на база данни.

РЕДАКТИРАНЕ:

В кода на оригиналната публикация, когато клеймото за време се преобразува в часовата зона UTC сървърът на базата данни преобразува timestamp with time zone тип да бъде нормален timestamp without time zone така че върнатата стойност няма информация за часовата зона. За да добавите обратно информация за часовата зона, можете например да добавите +02 към края на върнато времево клеймо по този начин:

select ('2010-01-01T00:00:00.000Z'::timestamptz AT TIME ZONE 'UTC')::text || '+00';

Което връща 2010-01-01 00:00:00+00 към драйвера, който може да бъде прочетен правилно и от pg драйвера.

Това на практика ще направи същото нещо, както просто задаването на SET TIME ZONE 'UTC'; в db сървър, когато връзката е създадена и просто връща колона timestamptz директно:

SET TIME ZONE 'UTC';
select '2010-01-01T00:00:00.000+02:00'::timestamptz;

Което ще върне 2009-12-31 22:00:00+00 .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как statement_timestamp() работи в PostgreSQL

  2. [Видео] Въведение в типовете данни JSON в PostgreSQL

  3. Преброяване на промените в колоната до конкретна стойност в postgres

  4. Намерете разликата между времевите марки в секунди в PostgreSQL с помощта на JOOQ

  5. Елиминирайте дублиращи се градове от базата данни