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');