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

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

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

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

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

Спасибо всем

Ответы [ 8 ]

5 голосов
/ 16 февраля 2010

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

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

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

date_default_timezone_set('UTC');

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

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

time();

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

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

4 голосов
/ 16 февраля 2010

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

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

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

Возможно связанный вопрос:

2 голосов
/ 18 февраля 2010

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

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

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

UPDATE:

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

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

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

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

1 голос
/ 25 марта 2010

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

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

  • Веб-сервер и база данных должны работать в одном часовом поясе компьютера. Я предлагаю UTC, поскольку это строительные блоки преобразования часовых поясов. Это обеспечит постоянство всех дат, хранящихся в вашей базе данных, и не пропускает ни одного раза, например, переход на 1 час между переходами на летнее время.
  • В верхней части всех ваших 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. (Думаю)

* ** тысяча сорок один тысяча сорок-два ** 1 043 * Пример * ** 1046 тысячи сорок-пять *

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

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

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

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

1 голос
/ 16 февраля 2010

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

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

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

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

0 голосов
/ 01 января 2018

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

$autoload['time_zone'] = date_default_timezone_set('Asia/Kolkata');
0 голосов
/ 19 сентября 2011

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

Codeigniter Date helper

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

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);
0 голосов
/ 25 марта 2010

Я использовал встроенное преобразование часового пояса MySQL. В базе данных все даты хранятся в формате UTC. В запросе на выбор я использовал 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');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...