Подтвердить что ты не робот

Bookshelf.js/Knex.js слишком "полезно" с столбцами UTC DATETIME

У меня есть таблица MySQL, и эта таблица имеет столбец DATETIME с именем datetime_utc. Это, как и следовало ожидать, дата и время в UTC. В моих моделях Bookshelf я определил виртуальный приемник, который преобразует его в формат строки ISO 8601 с использованием Moment.js. Моя модель выглядит примерно так:

bookshelf.plugin('virtuals');

exports.MyModel = bookshelf.Model.extend({
    tableName : 'my_table',
    idAttribute : 'id',
    virtuals : {
        datetime_iso : {
            get : function () {
                return moment.utc(this.get('datetime_utc')).format();
            }
        }
    }
});

Проблема заключается в том, что когда Bookshelf (или базовый Knex, который ее активирует) видит столбец DATETIME, он переносит значение в new Date(...), прежде чем передать его моему коду. Поскольку значение даты указано в формате UTC, но конструктор Date предполагает, что значение находится в локальном часовом поясе не-UTC сервера, я получаю объект Date, который имеет правильную дату в неправильном часовом поясе. После того, как Moment начнет работу над этой датой, все значения будут отключены фиксированным числом часов.

Я работал над этим, ища объекты Date и разлагая компоненты даты непосредственно в конструкторе Moment. Но он чувствует себя грубо:

get : function () {
    var dt = this.get('datetime_utc');

    if (dt instanceof Date) {
        dt = [
            dt.getFullYear(), dt.getMonth(), dt.getDate(),
            dt.getHours(), dt.getMinutes(), dt.getSeconds()
        ];
    }

    return moment.utc(dt).format();
}

Есть ли более чистый способ получить не-обернутое строковое значение YYYY-MM-DD HH:MM:SS из Bookshelf, или стенографию для создания нового объекта Moment из Даты с часовым поясом, который игнорируется/переводится в UTC?

4b9b3361

Ответ 1

Оказывается, это не вызвано ни Knex, ни книжной полкой, а скорее базой библиотеки node -mysql. Существует свойство соединения, называемое timezone, которое будет добавлено к каждому значению DATETIME, DATE, TIMESTAMP и NEWDATE перед его обработкой в ​​объект Date.

Knex передаст это свойство через node -mysql, пока он инициализируется:

require('knex')({
    "client": "mysql",
    "connection": {
        "host": "...",
        "user": "...",
        "password": "...",
        "database": "...",
        "timezone": "UTC"    <-- This is the culprit
    }
});