Каково поведение MYSQL по умолчанию при извлечении и вставке даты и времени? Встреча с интересной проблемой смещения часовых поясов - PullRequest
0 голосов
/ 04 июня 2019

У нас есть сервер в часовом поясе UTC в нашей тестовой среде, и мы заметили, что время в PDT некорректно указывалось.

Решение, которое мы придумали, состояло в том, чтобы преобразовать все в время UTC до его сохранения вбазы данных, а затем используя момент-часовой пояс для преобразования ее обратно в правильный часовой пояс локали при извлечении.

Я столкнулся с интересной проблемой, когда преобразование часового пояса в UTC работает правильно (например, если событие происходит в8:00 утра по тихоокеанскому времени, он хранится как 15:00 UTC, правильная разница составляет +7 часов).Все преобразования выполняются на стороне клиента, прежде чем они передаются на сервер в виде строки, пока они окончательно не сохранятся в базе данных.После выполнения запроса в базе данных я вижу его, как и ожидалось, в правильном формате 15:00.

Однако, когда я получаю данные, он добавляет дополнительные 7 часов и возвращает 22:00.Я вывел это из системы на всех маршрутах контроллера и подтвердил, что никаких других дополнительных изменений в объекте даты на сервере не происходит, поэтому я прав, полагая, что это поведение по умолчанию в MYSQL, о котором мне нужно знатьиз?

Кто-нибудь знает, почему это может происходить?

Использовал момент-часовой пояс для преобразования локального времени на стороне клиента в UTC и сохранения его в виде строки.Передача этого контроллеру для вставки в базу данных.

Подтвержденная база данных хранит информацию правильно, как и ожидалось.

Вывод неправильный с добавлением 7+ часов.

// This is on the client side where it formats the date using moment to convert it to UTC from locale time
function convertTimeToUTCTimezone(date) {
  const timezone = "America/Vancouver"; // TODO make this more applicable across different time zones in the future

  const formatDate = moment(date).format('YYYY-MM-DD HH:mm:ss');
  const formatTimezoneDate = moment.tz(formatDate, 
  timezone).utc().format('YYYY-MM-DD HH:mm:ss');
  return formatTimezoneDate;
}

Дата, введенная в форму: 2019-06-14 8:00:00 (8:00 по тихоокеанскому времени, то есть UTC - 7 часов)

Строка даты, переданная от клиента к серверу: 2019-06-14T15: 00: 00.000Z

Дата и время, которые я ожидаю увидеть с помощью запроса MySQL: (правильно) 2019-06-12 15: 00: 00

Я ожидаю, что время, извлеченное из него дляравно: (ожидается) 2019-06-14T15: 00: 00.000Z

Но я получаю: (выпуск) 2019-06-14T22: 00: 00.000Z

[ОБНОВЛЕНИЕ] база данных mysql, столбец определен как DATETIME

Вставьте пример:

// Using objectionJS
static async function insertToTable(formData) {
  // formData is an object of key-value pairs, keys matching database column names
  return this.query().insert(formData);
}

1 Ответ

0 голосов
/ 04 июня 2019

Мне любопытно, как выглядит значение столбца «Дата / Время» в вашем фактическом выражении MySQL «INSERT».Мне также любопытно, какой тип вы определили для своей таблицы MySql.

В общем, я бы порекомендовал:

  • Определение столбцов даты, времени и даты и времени каквведите «DATETIME»

  • Если возможно, установите ограничение по умолчанию и используйте «NOW ()» для ВСТАВКИ.При этом будут использоваться дата / время / часовой пояс сервера.

По этой ссылке:

https://www.vertabelo.com/blog/technical-articles/the-proper-way-to-handle-multiple-time-zones-in-mysql

Полный общий подход будетиметь два столбца DATETIME для хранения utc_datetime и local_datetime, в то время как столбец VARCHAR хранит строку часового пояса IANA (самая длинная на данный момент - «Америка / Аргентина / ComodRivadavia», которая имеет 32 символа).

Что бы вы ни решили, я бы подумал о том, чтобы выполнить большую часть "работы" на стороне MySql / server, по сравнению с вашим клиентом Javascript.

...