PHP, Codeigniter: Как установить дату/время на основе часового пояса/местоположения пользователей во всем мире в веб-приложении?

Я только что понял, добавляю ли я конкретную запись в свою базу данных MySQL - у нее будет дата/время сервера, а не конкретный пользователь и где они расположены, что означает, что моя функция поиска по дате бесполезна! Поскольку они не смогут выполнить поиск, когда они добавили его в свой часовой пояс, а не когда он был добавлен в часовой пояс серверов.

Есть ли способ в Codeigniter глобально установить время и дату, специфичные для местоположения пользователей (возможно, используя их IP), и каждый раз, когда я вызываю date() или time(), используется пользовательский часовой пояс.

То, что я действительно прошу, это возможно, как сделать мое приложение зависит от каждого часового пояса пользователей?

Может быть, лучше хранить каждый часовой пояс пользователей в своем профиле и иметь стандартное время (время сервера), а затем конвертировать время для каждого пользователя?

Спасибо всем

Ответ 1

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

Я не знаю CodeIgniter, поэтому не могу указать на правильные функции. Одна известная библиотека, которая является часовым зондом, - Zend_Date: Работа с часовыми поясами Я еще не работал с этими функциями, но они выглядят многообещающими.

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

Возможно, связанный с этим вопрос:

Ответ 2

Похоже, вам нужно сохранить все дату и время в вашей системе как время UTC (обычно называемое GMT). Это базовое время, когда все в мире рассчитывается с корректировками. (например: Центральное время - 6 часов от UTC)

В MySQL вы можете использовать UTC_TIMESTAMP(), чтобы получить текущее время UTC, пока ваш сервер и БД настроены с правильными настройками времени и часового пояса.

В PHP запустите это, чтобы установить временную метку PHP для UTC (вы запустите это в своем коде, чтобы поместить его на каждую страницу или в файл централизованного индекса):

date_default_timezone_set('UTC');

Или вы можете перейти непосредственно в PHP.INI и сказать ему использовать время UTC по всему миру. (это может не сработать, если у вас несколько сайтов на одной установке PHP.

И тогда в любой точке системы вам нужно получить текущее время UTC, которое вы можете просто вызвать:

time();

Затем для каждого пользователя в системе вам нужно будет спросить их, в какой временной зоне они живут, а затем, когда вы показываете время, выполните настройку для этого пользователя. Так что если это 5:00 вечера UTC, и я живу на Пасху США (-5), время будет 5:00 - 5 часов = 12:00 вечера.

Это может быть долгий процесс, чтобы получить право, но как только вы сделаете, ваши пользователи найдут его очень полезным, особенно на международном уровне.

Ответ 3

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

Просто спросите их о своем часовом поясе (обычно выбирайте в крупных городах в этот часовой пояс), а затем пересчитывайте:)

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

Кроме того, при пересчете вы можете использовать хелпер даты: http://ellislab.com/codeigniter/user-guide/helpers/date_helper.html

Ответ 4

Возьмем пример существующего веб-приложения, такого как WordPress и phpBB. У каждого пользователя есть свой собственный часовой пояс.

При получении содержимого от пользователя используйте local_to_gmt() функцию в "Помощник по дате" , затем сохраните содержимое в базе данных, используя дата gmt. При получении данных вы получите время в gmt. Получить настройку часового пояса пользователя, а затем отобразить данные в этом часовом поясе.

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

UPDATE:

Недавно я просмотрел последний проект, над которым я работал, с проблемой часового пояса. Подумав о различных сценариях, вот решение проблемы часового пояса:

  • Все данные, хранящиеся прямо сейчас используя время сервера. Изменение этого будет занимать время и подвержен ошибкам, поэтому я оставляю это так.
  • Для новых данных от пользователя, который задал дату контента определенному дата и время, я сохранил его в 2 колонка. Первый столбец предназначен для хранения данные как есть и используются для отображения это как есть. Второй столбец будет пересчет даты на основе часовой пояс пользователя на сервере часовой пояс. Этот столбец используется в WHERE (фильтр основан на дата сервера) и для ORDER (потому что это значение столбца все в тот же часовой пояс, который является часовой пояс).

Таким образом, я делаю только 1 расчет по часовому поясу, который предназначен для преобразования даты пользователя в дату сервера. Для отображения я показываю дату в соответствии с датой и временем сервера. Поскольку все данные, хранящиеся в том же часовом поясе, данные можно упорядочить по столбцу, в котором хранится значение даты сервера.

Для пользователя, установившего свой часовой пояс, дату из базы данных можно легко пересчитать, чтобы получить дату-время в пользовательском часовом поясе. Btw, в моем приложении, я показываю дату, используя плагины timeago jquery. Этим плагинам требуется время в формате ISO8601 (время UTC). local_to_gmt() функция в CodeIgniter может быть использована для этого.

Ответ 5

Очевидно, что скачок к британскому летнему времени (летнее время) - это большая путаница в мире программирования, и я действительно догнал эту путаницу.

Наилучшее возможное решение, которое я могу найти (которое я попытаюсь объяснить с объяснением) при использовании чувствительной к часовому поясу системы, таково:

  • Веб-сервер и база данных должны работать от одного и того же часового часового пояса. Я предлагаю UTC, поскольку это строительные блоки преобразования часовых поясов. Это гарантирует, что все даты, хранящиеся в вашей базе данных, будут постоянными и не будут пропускать такие моменты, как 1hour jump между летней экономией.
  • В верхней части всех ваших PHP-скриптов используйте date_default_timezone_set('Europe/London'); с конкретным часовым поясом пользователя.
  • При создании дат из представленных пользователем форм используйте gmmktime();, чтобы гарантировать, что созданная временная метка является UTC и не изменена заданным вами часовым поясом.
  • date(); может использоваться при показе дат, так как это преобразует метку времени в правильное время с учетом установленного вами часового пояса.
  • Если вам нужно показать дату в формате UTC, используйте gmdate(); с $gm_timestamp, который вы взяли из базы данных или создали с помощью gmmktime();.

Я написал этот бит PHP, чтобы понять ситуацию.

date_default_timezone_set('UTC');
$gmtime = gmmktime(2,0,0,03,29,2009);
$time = mktime(2,0,0,03,29,2009);
echo $gmtime.'<br />'.date('r',$gmtime).'<br />'.gmdate('r',$gmtime).'<br />';
echo $time.'<br />'.date('r',$time).'<br />'.gmdate('r',$time).'<br />';

date_default_timezone_set('Europe/London');
$gmtime = gmmktime(2,0,0,03,29,2009);
$time = mktime(2,0,0,03,29,2009);
echo $gmtime.'<br />'.date('r',$gmtime).'<br />'.gmdate('r',$gmtime).'<br />';
echo $time.'<br />'.date('r',$time).'<br />'.gmdate('r',$time).'<br />';

Надеюсь, я проделал хорошую работу, но я сомневаюсь в этом, потому что я все еще пытаюсь решить эту проблему в моей голове.

UPDATE:

Рад, что я сделал это, потому что теперь у меня возникают сомнения относительно введенных пользователем дат.

Чтобы получить введенную пользователем дату (с учетом их часового пояса), чтобы соответствовать соответствующей дате UTC в базе данных, вы должны поместить ее через mktime(). И затем используйте gmdate('U', $timestamp);, чтобы получить истинную метку времени UTC. (Я думаю)

Пример

Рассматривая это с отчетной стороны, пользователь использует часовой пояс "Европа/Лондон". В начале нашего PHP script мы вызываем date_default_timezone_set('Europe/London');, в то время как база данных (и все записи внутри) все еще находится в UTC.

Затем пользователь отправляет через них, что они хотят выбрать список книг, добавленных в базу данных между 25/03/2010 с 10:00 до 30/03/2010 14:00. Затем PHP script запускает переменные даты через mktime($hour, $minute, $second, $month, $day, $year), чтобы создать правильную метку времени UTC. Дата начала не изменится, но PHP знает, что дата окончания находится в часовом поясе BST, поэтому соответственно изменяет метку времени на UTC.

Когда результаты возвращаются пользователю, date('r', $date_added) может использоваться, чтобы показать пользователю дату, когда книга была добавлена ​​в базу данных в соответствии с установленной временной зоной.

Эта ссылка может помочь с пониманием, когда она изменится. http://www.daylightsavingtime.co.uk/

Ответ 6

Я использовал встроенное преобразование часового пояса MySQL. В базе данных все даты хранятся в формате UTC. В запросе select я использовал CONVERT_TZ для преобразования в пользовательский часовой пояс. Вы можете указать коды часовых поясов или часовые инверсии, такие как:

SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');

Но проблема в том, что это не подходит для летнего времени. Это особенно неприятно, поскольку многие части мира либо не соблюдают дневные сбережения, либо почитают его в разные сроки. Таким образом, если вы установите таблицы описания часовых поясов, вы можете использовать описательные имена, которые автоматически учитывают дневную экономию, например:

SELECT CONVERT_TZ('2004-01-01 12:00:00', 'UTC', 'US/Eastern');

Ответ 7

Codeigniter содержит помощник, который имеет дело со всеми функциями даты.

Codeigniter Date helper

команда gmt_to_local() должна помочь вам... третий параметр для "daylight_saving".

Takes a Unix timestamp (referenced to GMT) as input, and converts it to a localized timestamp based on the timezone and Daylight Saving time submitted. Example:
$timestamp = '1140153693';
$timezone = 'UM8';
$daylight_saving = TRUE;

echo gmt_to_local($timestamp, $timezone, $daylight_saving);

Ответ 8

Добавьте эту строку в autoload.php в папку приложения /config:

$autoload['time_zone'] = date_default_timezone_set('Asia/Kolkata');