Невозможно компенсировать разницу во времени при доступе к MySQL - PullRequest
0 голосов
/ 07 января 2019

Я храню дату и время в облаке Google mysql как CURRENT_TIMESTAMP. Я получаю доступ с помощью momentjs с параметром knex typeCast: (сервер Nodejs, размещенный в Google App Engine) и преобразую их в миллисекунды перед отправкой ответа обратно клиенту (android).

Реальная дата в базе данных: 2019-01-07 12: 37: 48

Что дает Android, когда я конвертирую дату в формат даты MYSQL: 2019-01-07 15: 37: 48 Обратите внимание на разницу в 3 часа.

Как конвертировать в Android:

public static SimpleDateFormat DB_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
  public static SimpleDateFormat DB_FORMAT_UNCHANGED = new 
  SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  "updated_at", > DB_FORMAT_UNCHANGED.format(milliseconds);
  "updated_at", > DB_FORMAT_UNCHANGED.format(milliseconds);//giving similar inaccurate result

Вопрос: Как я могу решить эту проблему таким образом, чтобы не мешать точности даты, куда пользователи моего приложения путешествуют по всему миру, так как вычитание смещения +3 GMT неэффективно

EDIT: Как конвертируется при доступе на сервере, внутри knex config:

const config = {
        user: 'user' ,
        password: 'pwpw' ,
        database: 'dbdb'  ,
        typeCast: function (field, next) {
            if (field.type === 'JSON') {
                return (JSON.parse(field.string()));
            }
            if (field.type === 'TINY' && field.length === 1) {
                return (field.string() === '1');
            }
            if (field.type === 'DATETIME') {
                return (moment(field.string()).valueOf());
            }
            return next();
        }
    };

Ответы [ 2 ]

0 голосов
/ 08 января 2019

MYSQL возвращает значения DATETIME столбца без смещения часового пояса. Поэтому, когда клиент интерпретирует их, они будут считываться как местное время часового пояса клиента.

Вместо этого вы можете использовать TIMESTAMP тип столбца, чтобы получить всегда интерпретируемое время с часовым поясом и всегда получать согласованное значение для метки времени Unix, даже если часовой пояс клиента отличается.

0 голосов
/ 07 января 2019

Проблема, с которой вы сталкиваетесь, заключается в том, что сервер генерирует временную метку в «некотором» часовом поясе, возможно, локальном для него. Ваше клиентское приложение не знает об этом. Этот часовой пояс сервера может даже измениться в будущем. Даже если оно не изменяется, оно может быть подвержено изменениям летнего времени.

Использование CURRENT_TIMESTAP замечательно, чтобы убедиться, что база данных всегда записывает правильное значение. Однако в последующих запросах, когда вам нужно отфильтровать данные по нему, ваше приложение должно знать часовой пояс, чтобы отправлять правильные значения в запросе.

MySQL DATATIME и TIMESTAMP типы данных не имеют альтернативных вариантов WITHOUT TIME ZONE. Похоже, вам нужен такой тип данных, который предлагают другие базы данных.

Учитывая это, я вижу решение, которое заключается в том, что вы устанавливаете часовой пояс на определенный во время конфигурации и соответственно конвертируете. То есть сервер и приложение должны постоянно использовать один и тот же. И да, я знаю, что это не то, что вам нужно, но вам нужно будет каждый раз выполнять преобразование часового пояса.

В некоторых ORM вы можете использовать «преобразователь типов» для автоматического преобразования при каждой вставке / обновлении / удалении / выборе. Возможно, у вас есть эта опция, чтобы не менять весь ваш код.

...