Можем ли мы всегда получать столбец даты в виде строки (varchar) с помощью knex и postgres?

2

У меня есть столбец в базе данных 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?

Теги:
knex.js
bookshelf.js
pg

4 ответа

9
Лучший ответ

Драйвер 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); 
1

Установка 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()
    }
  }
})
  • 0
    Я смог добиться того же эффекта, переопределив метод parse на модели. Но я думаю, я пойду с настройкой парсера типов в pg.
0

Для меня это не сработало решение

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

0

Чтобы получить время в соответствии с местным часовым поясом в строковом формате, мы можем использовать.

  var date =function(value) {
      /* you can use any other method for getting the date part */
        return value.toLocaleDateString()
  }

Дата ( '1990-12-30T18: 30: 00.000Z'); Дата (значение)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню