Вероятно нещата се провалят, защото когато правите заявки за дати и часове от база данни в определена часова зона и ефективно преобразувате типа на времевия печат да бъде времеви печат без часова зона. В този случай базата данни няма да изпрати информация на 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
.