У меня есть столбец в базе данных postgres с date
типа. Это столбец, похожий на день рождения, который является только датой и не требует временной части.
При извлечении этого столбца с помощью knex результатом является объект Date javascript. Предположительно, это new Date(row.birthday)
, и это результат, который отправляется клиенту.
Проблема в том, что значение, которое получает клиент, находится в стандартном формате ISO 8601 с временной частью и Z
Когда клиент пытается создать новый объект Date из этой строки, клиент может иметь ошибочное значение даты, основанное на местонахождении клиента.
Например:
Date: 2018-06-15
Date sent to client: 2018-06-15T00:00:00Z
Client in +5:00 | Client in -5:00
2018-06-16 05:00:00 | 2018-05-15 10:00:00
Это нормально, если сервер находится в UTC, мы можем просто добавить смещение часового пояса клиента и получить исходную дату, но это немного хрупко, и оно ломается во время локального развития (чего нет в UTC).
Простое решение состоит в том, чтобы просто отправить часть даты в виде строки для клиентов. Но это потребует сохранения даты в качестве varchar
на сервере, чего мы не хотим делать. Мы потеряем ограничение форматирования дат и усложним выполнение вычислений на основе даты с помощью SQL.
Мы могли бы использовать столбец как varchar
при выборе столбца, но нам нужно иметь ум, чтобы делать это каждый раз, когда эта таблица извлекается. Это также означает, что нам нужно обойти ORM (Книжная полка) для работы с этой таблицей.
Есть ли простой способ указать либо в кнуте, либо в книжной полке, либо в postgres, что колонку нужно сохранить в качестве date
со всеми сопровождающими ограничениями, но всегда выбираться как varchar
?
Драйвер node-postgres - это часть, которая фактически создает объекты Date() из данных, отправляемых из столбцов даты (https://node-postgres.com/features/types#date-timestamp-timestamptz)
С помощью postgres вы можете модифицировать парсеры типа node-pg, как описано здесь https://github.com/brianc/node-pg-types
Типы дат типа oid, который равен 1082, можно получить с помощью следующего запроса
select typname, oid, typarray from pg_type where typname = 'date' order by oid;
Поэтому, чтобы переопределить тип даты для передачи в виде строки, достаточно сделать это перед настройкой соединения с БД (я полагаю, это можно сделать, например, в knexfile.js):
var types = require('pg').types;
// override parsing date column to Date()
types.setTypeParser(1082, val => val);
Установка typeParser
для pg
, вероятно, лучший ответ, но вы также можете использовать Bookshelf Processor плагину изменить то, что конкретный date
атрибут выглядит следующим образом:
bookshelf.plugin('processor')
var MyModel = bookshelf.Model.extend({
tableName: 'stuff',
processors: {
date: function(value) {
/* you can use any other method for getting the date part */
return value.toLocaleDateString()
}
}
})
Для меня это не сработало решение
types.setTypeParser(1082, val => val);
Для меня это сработало с использованием моментов
import * as moment from 'moment';
types.setTypeParser(1114, str => moment.utc(str).format());
Кредиты Oleksii Rudenko
https://60devs.com/working-with-postgresql-timestamp-without-timezone-in-node.html
Чтобы получить время в соответствии с местным часовым поясом в строковом формате, мы можем использовать.
var date =function(value) {
/* you can use any other method for getting the date part */
return value.toLocaleDateString()
}
Дата ( '1990-12-30T18: 30: 00.000Z'); Дата (значение)
parse
на модели. Но я думаю, я пойду с настройкой парсера типов в pg.