2015-11-10 1 views
1

Я использую Laravel/PHP/MySQL и сохраняю все даты и время в UTC.Как рассчитать среднее время суток с учетом различий в часовых поясах?

Пользователь может выбрать часовой пояс (например, восточный), ввести дату и время, а дата и время будут преобразованы в UTC перед сохранением. При извлечении он будет преобразован в выбранный часовой пояс пользователя.

Мой вопрос: как вы можете получить среднее время суток из серии записей с учетом часового пояса (желательно в запросе базы данных)? Следующий вопрос касается среднего времени дня в PHP, но не проблемы с часовым поясом.

How to calculate average time

Вот что я делаю:

SEC_TO_TIME(AVG(TIME_TO_SEC(TIME(flights.departed_at))))) AS average_time 

Это работает для записей, которые охватывают Daylight Saving/стандартное время в регионе, который наблюдает за исключением его.

ПРИМЕР: У вас может быть запись с датой UTC 2015-08-18 11:00:00, введенная пользователем в EDT по адресу 2015-08-18 07:00:00. Затем у вас есть вторая запись, введенная с датой UTC 2015-11-10 12:00:00 пользователем в EST по адресу 2015-11-10 07:00:00. Если вы попытаетесь рассчитать среднее время суток, оно должно быть равно 07:00:00, но вместо этого результат будет 07:30:00.

Любые идеи, как преодолеть это? Я подхожу к этому все неправильно?

Заранее спасибо.

+0

дневной свет. На основе дат, один - 7 часов, а один - 8. Это средний показатель до 7.5 часов. –

+2

вы храните все в utc и настраиваете только время для вывода. все остальное будет просто невероятно болезненным и крайне неэффективным, поскольку вы постоянно прыгаете между часовыми поясами, как пьяная блоха. –

+0

@MarcB Это то, что я делаю. Я конвертирую пользовательский ввод из ETD или EST в UTC, сохраняя его, затем показываю его как ETD или EST. Проблема заключается в вычислении среднего времени от записи, введенной в EDT, и записи, введенной в EST, оба преобразованы в UTC. – CaveSpider

ответ

0

Если у вас есть все время, сохраненное в Z, и если ваша база данных MySQL имеет timezones loaded correctly, вы можете использовать имя часового пояса zoneinfo, чтобы получить местное время. Например,

SELECT CONVERT_TZ('2015-08-01 11:00', 'UTC', 'America/New_York'), 
     CONVERT_TZ('2015-12-01 12:00', 'UTC', 'America/New_York') 

дает

2015-08-01 07:00 2015-12-01 07:00 

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

Таким образом, вы можете получить время суток, по местному времени, с выражением, как это:

TIME(CONVERT_TZ(utc_time_column, 'UTC', 'America/New_York')) 

Затем в среднем те времена-оф-день в обычном порядке.

+0

Спасибо! Именно такой тип решения я искал! – CaveSpider

1

Одним словом, ваш код работает правильно. После того, как дата указана в формате UTC, вам нужно будет пересчитать, было ли оно введено (1) во время летнего времени, (2) кем-то, кто фактически соблюдает летнее время, и (3) в месте, которое распознает дневной свет экономия времени.

Я действительно могу думать только об одном способе подхода к этому.

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

+0

Это был первый подход, который я рассмотрел, но решение @OllieJones - это то, что я искал. Спасибо, что ответили! – CaveSpider

+1

А, ок. Поскольку он не упоминался в вашем вопросе, я не хотел предполагать, что вы уже сохранили информацию TZ. Тогда его ответ определенно более уместен. – Trip

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