Вероятно, что-то не получается, потому что, когда вы запрашиваете дату / время из базы данных в определенном часовом поясе и эффективно конвертируете тип метки времени в метку времени без часового пояса. В этом случае база данных не будет отправлять информацию в knex о том, в каком часовом поясе было возвращено время.
Таким образом, knex (или, точнее, драйвер pg, который использует knex) интерпретирует вашу временную метку как местное время, которое зависит от настройки часового пояса сервера приложений, на котором работает knex.
Вы можете извлекать время точно так же, как в формате UTC, и выполнять преобразование часового пояса на стороне JavaScript с помощью библиотеки моментов или luxon (IMO лучше для обработки часового пояса).
Другим решением было бы сообщить pg driver, что отметка времени и отметка времени с типами часовых поясов не должны преобразовываться в JavaScript
Date
объекты.
Это можно сделать так (https://github.com/brianc/node-pg-types):
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';
на сервере базы данных при создании соединения и просто вернуть столбец timestamptz напрямую:
SET TIME ZONE 'UTC';
select '2010-01-01T00:00:00.000+02:00'::timestamptz;
Который вернет 2009-12-31 22:00:00+00
.