2015-01-18 2 views
4

У меня есть куча событий, хранящихся в моей базе данных. Каждое событие имеет время начала, которое хранится как DATETIME в UTC. Каждый пользователь может выбрать свой часовой пояс.Как группировать по дате, составляя часовые пояса и DST?

Я хочу отобразить календарь, который показывает количество событий в каждый день месяца. Я не могу GROUP BY DATE(start_dt), потому что пользовательский день [обязательно] не начинается в 00:00:00 UTC. Кроме того, в часовом поясе пользователя может быть переключатель DST в середине месяца.

Является ли мой единственный выбор для получения каждого отдельного события за данный месяц, а затем группировки и подсчета их на моем серверном языке?

ответ

1

вы можете промежуточно переключиться на TZ пользователей:

SET @@session.time_zone = "+05:00"; 
    select ... from .. group by MONTH(datefield); 
    SET @@session.time_zone = @@global.time_zone; 

просто найдено: How do I set the time zone of MySQL?

+0

Изменение часового пояса на самом деле не повлияет на мои поля DATETIME? – mpen

+4

К сожалению, это не будет. Из документа MySQL: «Текущий параметр часового пояса не влияет на значения, отображаемые такими функциями, как UTC_TIMESTAMP() или значениями в столбцах DATE, TIME или DATETIME. Также нет значений в этих типах данных, хранящихся в UTC, часовой пояс применяется для их только при преобразовании из значений TIMESTAMP. Если вы хотите, чтобы арифметика, специфичная для локали, для значений DATE, TIME или DATETIME, конвертировала их в UTC, выполняла арифметику, а затем конвертировала обратно ». –

+0

нет! просто попробуйте 'SET @@ session.time_zone =" +03: 00 "; выберите сейчас() из двойного; 'Это не изменит ваши часы ... –

1

К сожалению DATETIME столбцов сохраняются без информации часового пояса:

Настройка зоны текущего времени не влияют на значения, отображаемые такими функциями, как UTC_TIMESTAMP() или значения в столбцах DATE, TIME или DATETIME. Также нет значений в тех типах данных, которые хранятся в UTC; часовой пояс применяется для них только при преобразовании значений TIMESTAMP. Если вы хотите, чтобы арифметика, специфичная для локали, для значений DATE, TIME или DATETIME, конвертировала их в UTC, выполняла арифметику и затем конвертировала обратно. [MySQL Docs]

К счастью, это не означает, что дата/время функции должны работать с поддержкой часовых поясов, но только на TIMESTAMP колонн. После того, как в столбце TIMESTAMP функции даты/времени должны учесть @@session.time_zone, которые вы можете изменить по мере необходимости, чтобы получить разные часовые пояса.

Итак, ваш выбор, чтобы сохранить ваши таблицы с DATETIME столбцами, и делать все группировки самостоятельно, или преобразовать эти столбцы TIMESTAMP и пусть MySQL это сделать - но если столбцы уже находятся в различных и противоречивых часовых поясах, вы» будете иметь вашу работу вырезал для вас ...

+1

Вам просто нужно помнить, что tzdata не задан в камне, и как только у вас есть какие-то даты, преобразованные в временные метки, вам не нужно будет возвращать их правильно после изменения правил часового пояса , –

7

вы можете попробовать

SELECT ... FROM ... GROUP BY DATE(CONVERT_TZ(start_dt,'UTC','America/Vancouver')) 

Обратите внимание, что вам нужно load the timezone data into MySQL прежде, чем это будет работать.

+1

Или используйте числовое смещение в качестве третьего параметра для 'CONVERT_TZ()' ([manual] (http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_convert -tz)), так что он не требует таблиц часовых поясов, например. 'CONVERT_TZ ('2004-01-01 12:00:00', 'UTC', '+ 10:00');' – RandomSeed

+2

@RandomSeed Проблема с этим - DST. Смещение в начале месяца может быть не таким, как в конце месяца. – mpen

+0

@RandomSeed Вы сделали небольшую ошибку в примере. Это должно быть: 'CONVERT_TZ ('2004-01-01 12:00:00', '+ 00:00', '+ 10:00');' потому что использовать 'UTC' вместо' +00: 00' еще в результате получится 'NULL'. – instead

Смежные вопросы