Время моего сервера в GMT, и я делаю следующее, когда кто-то приходит в Интернет.
// Set a default timezone $defaultTimeZone = 'America/Toronto'; // load the user, if they are online... $onlineUser = new user(); if (isset($_SESSION['user_id'])) { if ($onlineUser->loadUser($_SESSION['user_id'])) { $defaultTimeZone = $onlineUser->timeZone; } } // set time zones date_default_timezone_set($defaultTimeZone); $db->query("SET SESSION time_zone = '".$defaultTimeZone."'");
Итак, моя проблема заключается в том, что … когда кто-то делает что-то, он хранит дату / время в местном времени пользователей … вызывает у меня целый ряд проблем.
Все, что я хочу, это все, что нужно хранить в GMT, но пользователи видят и взаимодействуют с данными в их локальном часовом поясе.
РЕДАКТИРОВАТЬ:
Вот как я обновляю статус пользователей:
public function updateStatus() { global $db, $common, $config; // update the user record $data = array( 'date_last_active' => new Zend_Db_Expr('NOW()') ); $db->update('users', $data, 'user_id='.$this->userId); }
Вот моя функция, чтобы превратить дату в секундах …
public function dateTimeToUnixTime($dateString) { if (strlen($dateString) < 10) { return ""; } $parseDateTime = split(" ", $dateString); $parseDate = split("-", $parseDateTime[0]); if (isset($parseDateTime[1])) { $parseTime = split(":", $parseDateTime[1]); } else { $parseTime = split(":", "00:00:00"); } return mktime($parseTime[0], $parseTime[1], $parseTime[2], $parseDate[1], $parseDate[2], $parseDate[0]); }
И, наконец, как я сравниваю даты:
$date = $oUser->dateLastActive; $lastSeen = abs($common->dateTimeToUnixTime(date('Ymd H:i:s')) - $common->dateTimeToUnixTime($date)); if ($lastSeen < 300 ) { echo "<font size='1' color='green'><strong>Online</strong></font>"; } if ($lastSeen >= 300) { echo "<font size='1' color='black'><strong>Offline</strong></font>"; }
Трюк здесь заключается в том, чтобы знать, какой тип столбца date_last_active
. У меня было достаточно опыта с TIMESTAMP
и DATETIME
чтобы знать, что один переводит (и выполняет) переменную сеанса MySQL time_zone, а другой – нет.
mysql> SET SESSION time_zone = 'America/New_York'; Query OK, 0 rows affected (0.00 sec) mysql> create table timetest ( dt datetime NULL, ts timestamp NOT NULL DEFAULT 0 ); Query OK, 0 rows affected (0.06 sec) mysql> INSERT INTO timetest ( dt, ts ) VALUES ( UTC_TIMESTAMP(), UTC_TIMESTAMP() ); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO timetest ( dt, ts ) VALUES ( NOW(), NOW() ); Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM timetest; +---------------------+---------------------+ | dt | ts | +---------------------+---------------------+ | 2009-06-27 17:53:51 | 2009-06-27 17:53:51 | | 2009-06-27 13:53:54 | 2009-06-27 13:53:54 | +---------------------+---------------------+ 2 rows in set (0.00 sec) mysql> set session time_zone='UTC'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM timetest; +---------------------+---------------------+ | dt | ts | +---------------------+---------------------+ | 2009-06-27 17:53:51 | 2009-06-27 21:53:51 | | 2009-06-27 13:53:54 | 2009-06-27 17:53:54 | +---------------------+---------------------+ 2 rows in set (0.00 sec)
Итак, вот что я делаю:
my.cnf
меня есть: time_zone=UTC
чтобы избежать проблем в MySQL, а в PHP я date_default_timezone_set('UTC')
. UTC_TIMESTAMP()
вместо NOW()
– один – это UTC, один использует локальный (сеансовый) часовой пояс. Если вы следуете первой точке, выше, используйте UTC_TIMESTAMP (). set time_zone='
для отображения пользователю, set time_zone='
local_time_zone '
перед отображением чего-либо. Надеюсь, этого достаточно, чтобы понять, как подойти к этому. Дайте мне знать, если у вас возникнут дополнительные вопросы.
Я думаю, что функция NOW () Mysql сохраняет текущий часовой пояс, что определенно является проблемой, я бы проверял CONVERT_TZ (dt, from_tz, to_tz), это может решить вашу проблему, также я считаю, что время php () возвращает время сервера, вы может сохранить это вместо этого. единственным недостатком является либо преобразование возвращаемого значения в значение datetime / timestamp, либо сохранение его как varchar. недостатком использования convert_tz является то, что вы можете получить некоторые уродливые запросы, и вам нужно будет определять текущий часовой пояс каждый раз, когда вы его используете.
Я потратил почти полдня на решение этой проблемы, и я думаю, что мне нужно помогать другим. Поэтому я предоставляю вам ряд рекомендаций, чтобы избежать проблем с часовым поясом.
Прежде всего у вас есть два варианта использования MYSQL TIMEZONE или PHP TIMEZONE , не смешивайте их друг с другом, если вы хотите держаться подальше от кошмаров часовых поясов.
ЕСЛИ ВЫ ВЫБИРАЕТЕ MYSQL TIMEZONE:
ДЛЯ ВСТАВКИ:
fieldname: yourfieldname datatype: timestamp default: CURRENT_TIMESTAMP
ДЛЯ ОБНОВЛЕНИЯ:
UPDATE YOUR_TABLE SET youfieldname = NOW() WHERE CONDITION;
ДЛЯ ВЫБОРА:
Единственное, что вам нужно сделать, это установить требуемый часовой пояс для вашего приложения. Mysql автоматически конвертирует сохраненную метку времени в указанный часовой пояс.
mysql>SET SESSION time_zone='offset'; mysql>SELECT NOW();
пример смещения: +05: 30 для Индии, так же найти смещение для вашего региона.
Теперь вы получите нужную дату и время из mysql.
ЕСЛИ ВЫ ВЫБИРАТЬ PHP TIMEZONE :
Просто установите часовой пояс своего желания, используя эту функцию:
date_default_timezone_set('America/Los_Angeles');
ДЛЯ ВСТАВКИ:
fieldname : ваше поле
Тип данных: datetime
Используйте функцию даты PHP для хранения даты и времени:
$sql = "INSERT INTO timetest ( YOURDATETIMEFIELD ) VALUES ('".date('Ymd H:i:s')."')";
ДЛЯ ОБНОВЛЕНИЯ:
$sql = "UPDATE YOUR_TABLE SET yourdatetimefield = '".date('Ymd H:i:s')."'";
ДЛЯ ВЫБОРА:
$sql = "SELECT yourdatetimefield FROM yourtable";
Надеюсь, это поможет вам.