Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Разные часовые пояса, последний визит пользователя
 
 автор: Лена   (05.07.2010 в 16:42)   письмо автору
 
 

Время последнего посещения в базе хранится в int(11), надо его из базы вывести на страницу с учетом часового пояса клиента.
Запуталась совсем, не знаю, как высчитать смещение. Как я поняла, смещение к востоку на JS отрицательное, на сервере(PHP) - наоборот, положительное. Вот с этим и загвоздка - прибавлять или вычитать или что вообще нужно делать...
То, что не получается - большими буквами в комментах.

<html>
<head>
<script>
//заполнение результата даты нулями
function fillNull(number){
    return number<10?"0"+number:number;
}

//получить серверное время, преобразовать его в местное
function ClientTime(st){
var clientDate = new Date();
var clientOffset = clientDate.getTimezoneOffset()/60; //смещение на клиенте, разница в секундах

serverDate = new Date(st);

//ВОТ ЗДЕСЬ НАДО ВЫСЧИТАТЬ СМЕЩЕНИЕ, ВРЕМЯ СЕРВЕРНОЕ +(-) ОФСЕТ
//var ofs = serverDate + clientOffset;

//создать объект с учетом смещения
st_ofs = new Date(ofs);

//выводим с учетом смещения и заполняем нулями
return fillNull(st_ofs.getYear())+"-"+fillNull((st_ofs.getMonth()+1))+"-"+fillNull(st_ofs.getDate())+"
 "+fillNull(st_ofs.getHours())+":"+fillNull(st_ofs.getMinutes())+":"+fillNull(st_ofs.getSeconds());
}
</script>
</head>
 <body>
  <div>
<?php

include("dbopen.php");
$sql "SELECT lastVisit FROM users WHERE id=10";
$res mysql_query($sql);
if(!
$res)exit("Error in " $sql mysql_error());
$time mysql_result($res,0)*1000//время на сервере, переводим в миллисекунды
?>
  <script>
  //выводим последний визит пользователя с учетом смещения
    document.write(ClientTime(<?php echo $time?>))
   </script>
   </div>
  </body>
</html>

  Ответить  
 
 автор: sim5   (05.07.2010 в 17:26)   письмо автору
 
   для: Лена   (05.07.2010 в 16:42)
 

Я же вам уже говорил, что вам нужно знать только смещение часового пояса. Можно его получить и на клиенте, а можно по IP адресам региона знать это смещение. Все, остальное нужно проделывать в UTC формате времени.
Например, мой часвой пояс +9, вот сервер отдаст мне время мое:
<?
$timezone  
9
echo 
gmdate("Y-m-d H:i:s"time() + 3600*($timezone+date("I")));

Если вы хотите оперировать на клиенте со временем, то вам клиенту нужно передать смещение часового пояса сервера, и пользоваться JS-методами времени для UTC формата.

  Ответить  
 
 автор: Лена   (05.07.2010 в 17:38)   письмо автору
 
   для: sim5   (05.07.2010 в 17:26)
 

По IP определять я не хочу, читала, что неточно считает.
На сервере вы уже в принципе показали, что делать, я только дописала смещение на JS.

<script>
function ClientTime(){
var clientDate = new Date();
var clientOffset = clientDate.getTimezoneOffset()/60; //смещение на клиенте, разница в секундах
 return clientOffset;
 }
 </script>
 
 <?
$timezone  
"<script>ClientTime();</script>";
echo 
gmdate("Y-m-d H:i:s"time() + 3600*($timezone+date("I")));
?>


Если на JS, почему нужно пользоваться методами для UTC формата?

  Ответить  
 
 автор: sim5   (05.07.2010 в 17:52)   письмо автору
 
   для: Лена   (05.07.2010 в 17:38)
 

Если вам нужны часы на клиенте, которые будут синхронизированы с часами сервера, тогда еще можно понять передачу смещения пояса сервера клиенту, и JS-вычисления времени на клиенте. Но делать это нужно методами setUTC..., getUTC... и т.п., потому как они для этого и предназначены.
Если требуется вывести одноразово клиенту время (чего-то там последний раз посещаемого), переведя время сервера во время клиента, то достаточно воспользоваться функцией gmdate() с учетом смещения клиента, без всяких телодвижений на клиенте.

PS. Время смещения клиента, это просто один метод - getTimezoneOffset() (в минутах), без всяких пользовательских функций (поправка, имел ввиду без сложных вычислений):
<script> 
 document.location = "url?tmz=" + new Date().getTimezoneOffset()/60;
</script>

Только учтите, что с клиента будет передано смещение с учетом летнего времени (например, от меня вернет -10), то есть, строка кода:
<?
echo gmdate("Y-m-d H:i:s"time() + 3600*($timezone+date("I")));
//не должна это (Daylight Savings Time, DST) учитывать:
echo gmdate("Y-m-d H:i:s"time() - 3600*($timezone));

  Ответить  
 
 автор: Лена   (05.07.2010 в 21:20)   письмо автору
 
   для: sim5   (05.07.2010 в 17:52)
 

Мне, можно сказать, единоразово надо.
Социальная сеть. Аккаунт пользователя. Когда пользователь выходит из аккаунта, в базе фиксируется время его последнего посещения.
Это время надо вывести на страницу в аккаунте, чтобы другие пользователи-его друзья(из разных часовых поясов) видели, когда этот пользователь был на сайте.

Последние две строки не поняла. Почему "+" или "-".
Смещение на клиенте учитывает летнее время. Почему на сервере не надо учитывать это летнее время?

  Ответить  
 
 автор: sim5   (05.07.2010 в 21:35)   письмо автору
 
   для: Лена   (05.07.2010 в 21:20)
 

Если аккаунт, то кто мешает при регистрации пользователя запрашивать его часовой пояс? Вывести подобный как в Windows список часовых поясов не сложно, а зная часовой пояс пользователя достаточно будет:
<?
$user_timezone  
плюс/минус N;  
echo 
gmdate("Y-m-d H:i:s"time() + 3600*($user_timezone+date("I")));

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

Почему + и -, да потому, что РНР смещения к востоку выдает положительными, а к западу отрицательные, а методы JS будут выдавать обратные значения - к востоку отрицательные, к западу положительные.

Если вам клиент возвращает смещение с учетом перехода на летнее время, то добавив 1 час летнего времени к полученному на сервере, получим +2 часа летнего времени.

Запрашивайте при регистрации часовой пояс клиента и головной боли будет меньше.

  Ответить  
 
 автор: Лена   (05.07.2010 в 22:09)   письмо автору
 
   для: sim5   (05.07.2010 в 21:35)
 

>Если аккаунт, то кто мешает при регистрации пользователя запрашивать его часовой пояс?

Не хотят, чтобы так было. Я предлагала, не хотят и все

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

Я на той неделе в трех сетях зарегистрировалась, чтобы посмотреть "а как у них", где-то я это отставание видела, там секунд на 5-10 получается, не больше. Мне это не критично.

Приходит мне смещение от клиента. Как я узнаю, поддерживает ли этот часовой пояс переход на летнее время? Мне составить список всех, кто поддерживает, и по нему проверять?

  Ответить  
 
 автор: sim5   (05.07.2010 в 22:49)   письмо автору
 
   для: Лена   (05.07.2010 в 22:09)
 

Не хотят, это их проблемы, недальновидные значит.
Вот пример. Когда-то на Яшка-ТВ смотрел расписание программ, оказалось, что мое время указано не верно, хотя часовой пояс мой был указан верно. Написал в техподдержку, подправили (хотя НТВ так и осталось "кривое"). Но вот опять заглянул на Яшка-ТВ, читая эту тему, и что наблюдаю - опять время не мое, хотя по IP регион опознается верно. Верно судя по Яшка-логике - Благовещенск +6. Надо полагать, что они к московскому GMT плюсуют разницу относительно московскому времени (у нас с Москвой +6 часов).
На этой же странице есть часы, отображающие время на клиенте - врут они у меня примерно на полторы минуты. У нас интернет, это далеко не Москва и Питер, и задержки при загрузки бывают такие, что... Так что "Я на той неделе в трех сетях зарегистрировалась, чтобы посмотреть "а как у них", где-то я это отставание видела, там секунд на 5-10 получается, не больше. Мне это не критично.", это еще не повод для радости.
Плюс задержки у меня могут возникать, когда все три компьютера домашних работают в сети (вход в интернет с одного), и один из них закачкой занимается. А разве такой ситуации быть не может у других?

Зачем вообще гнать время сервера клиенту, чтобы из него получить время клиента? Никого времени посредством JS не надо, вам нужно только смещение часового пояса от него, а вот с переходом оно на летнее время или нет, в этих данных не указывается, да и недавно в России в этом плане произошла небольшая революция. Некоторые бывшие республики наши вообще отказались от переходна на летнее время. Впрочем можете почитать тут.

PS. Переход на летнее время у клиента, происходит автоматически, если отметить "галочку". Я не думаю, что регионы не переходящие на летнее время от нечего делать дают команду компьютеру переводить его. Следовательно вам и не требуется узнавать, с переходом смещение или без оного - не учитывайте его на сервере и все будет ОК. Уверен.

  Ответить  
 
 автор: Лена   (05.07.2010 в 23:15)   письмо автору
 
   для: sim5   (05.07.2010 в 22:49)
 

Я уже согласилась, что буду на сервер передавать от клиента смещение.
Почитала литературу и поняла, что как-то отследить по часовым поясам переход на летнее время вообще нереально. Страны одного часового пояса то переходят на летние часы, то не переходят - кто как хочет, тот так и делает.

т.е. мне просто делать echo gmdate("Y-m-d H:i:s", time() + 3600*($user_timezone)); ?

Мне в url передавать пояс не надо, почему если я делаю так:
$timezone = "<script>document.write(new Date().getTimezoneOffset()/60);</script>";
echo gmdate("Y-m-d H:i:s", time() + 3600*($timezone));

у меня ничего не выводит?

  Ответить  
 
 автор: Trianon   (06.07.2010 в 02:05)   письмо автору
 
   для: Лена   (05.07.2010 в 23:15)
 

Я вот чего не понимай.
А зачем вообще трогать эти самые смещения?
Или Вы хотите вычислять местное клиентское время на сервере?

  Ответить  
 
 автор: Лена   (06.07.2010 в 12:22)   письмо автору
 
   для: Trianon   (06.07.2010 в 02:05)
 

>Я вот чего не понимай.
>А зачем вообще трогать эти самые смещения?
>Или Вы хотите вычислять местное клиентское время на сервере?

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

  Ответить  
 
 автор: Trianon   (06.07.2010 в 12:27)   письмо автору
 
   для: Лена   (06.07.2010 в 12:22)
 

так и выводите (форматируйте) время клиентскими (JS) средствами.

  Ответить  
 
 автор: sim5   (06.07.2010 в 06:55)   письмо автору
 
   для: Лена   (05.07.2010 в 23:15)
 

>Мне в url передавать пояс не надо

А как вы узнаете смещение клиента, если хоязин напрямую не хочет об этом его спрашивать?

>почему если я делаю так:
>$timezone = "<script>document.write(new Date().getTimezoneOffset()/60);</script>";
>echo gmdate("Y-m-d H:i:s", time() + 3600*($timezone));
>у меня ничего не выводит?

А с чего бы оно должно выйти? Вы фактически пытаетесь, будучи еще на сервере, выполнить JS-код - document.write(new Date().getTimezoneOffset()/60) ! А такое разве возможно? Даже если вы выполните этот js-сценарий на клиенте, то что вам от этого будет? Ну запишет на странице это смещение, и что?

Время смещения (это разница по отношению к GMT/UTC) к востоку от Гринвича JS вернет как отрицательное значение, поэтому это смещение на сервере надо вычитать, иначе, например, я буду иметь разницу с Москвой не 6 часов, а 9 (с учетом летнего времени все 10). К тому же, во время всего обсуждения имелось ввиду (с моей стороны конечно), что разговор о стране любимой, где часовые пояса это час, два, три..., но есть смещения и 3:30 и 9:30. То есть, совсем не обязательно получать время смещения от клиента деленное на 60 минут. Хотите вы (или хозяин) того или нет, вам в любом случае нужно узнавать часовой пояс клиента, прибавляя его, или разницу в минутах по отношению к GMT js-методом, вычитая ее.

Рассуждая здраво, можно сказать, что не стоит дергать постоянно клиента, дабы узнать смещение. Тогда, например, можно так:
<?
session_start
();
//получили смещение клиента, его можно сохранить в базе
if (isset($_GET['tmz'])) $_SESSION['tmz'] = intval($_GET['tmz']);
if(!isset(
$_SESSION['tmz'])) { //если смещение клиента не известно, получаем
  //смещение пользователя, может быть с учетом перехода на летнее время
  
echo '<script>document.location = "?tmz=" + new Date().getTimezoneOffset();</script>';
  exit;
}
//это время сервера, Москва +3 GMT, с учетом летнего времени, хранящееся в базе
$time_server '2010-07-06 19:15:36';
//считаем, что часовой пояс клиента +9 GMT, разница с Москвой +6 часов
//получаем время клиента
echo 'Время московское: ' .$time_server', время клиента: '
gmdate("Y-m-d H:i:s"strtotime($time_server) - 60*($_SESSION['tmz']));
//получим
//Время московское: 2010-07-06 19:15:36, время клиента: 2010-07-07 01:15:36
?>

В часовой пояс такое понятие как DST не включено, и в расчетах универсального времени с использованием часового пояса мы это учитываем, добавляя date('I'). Но клиент возвращает разницу уже с учетом летнего времени, если она есть, поэтому, добавив date('I') и в этом случае, получим 1 час лишнего времени.
Да, есть "счастливые" пользователи, которые "часов не наблюдают", у которых может быть и летнее время, хотя и не надо его, а может вообще компьютер показывает время эпохи неолита, но это их проблемы. Поэтому отслеживать переходы времени не стоит, все будет происходить автоматом, главное чтобы сервер учитывал этот переход, если он есть в его поясе.

На мой взгляд интересней другой момент - возможность устанавливать/изменять часовой пояс пользователю или получать разово, хранить и где хранить. Третий вариант, это постоянно запрашивать getTimezoneOffset() клиента, и хотя можно задействовать ajax для этого, но...
Вариант получать разово и сохранить в базу, без возможности изменения, чреват недостатком. Например, вам улыбнулась удача, вы урвали путевку к нам, в солнечный Магадан, и аж на 3 месяца, ну там манго, киви покушать, у пальмы позагорать. А у вас в базе хранится киевский часовой пояс, а охота все три месяца видеть время солнечного Магадана. Можно конечно залезть в свои паспортные данные и изменить, если возможно. Но есть и другой путь - почему бы на странице не выводить список выбора часового пояса, и хранить его не в базе, а в cookies? Тогда в солнечном Магадане оперативно указали, что вы под пальмою, а при возврате в дождливый унылый Киев, вернули все на круги своя.

Я бы так поступил, в смысле, на вашем месте отдыхал бы в Магадане. ;-)

  Ответить  
 
 автор: Лена   (06.07.2010 в 12:43)   письмо автору
 
   для: sim5   (06.07.2010 в 06:55)
 

>но есть смещения и 3:30 и 9:30. То есть, совсем не обязательно получать время смещения от клиента деленное на 60 минут

я делаю для немцев и эмигрантов. Маловероятно, что на сайт придет какой-то житель Мьянмы или Афганистана, где смещение по полчаса.


>На мой взгляд интересней другой момент - возможность устанавливать/изменять часовой пояс пользователю или получать разово, хранить и где хранить.

Если хранить в базе, получается тоже накладно - как только к пользователю на страницу кто-то зайдет, в базу придется делать запрос, чтобы узнать часовой пояс. cookies мне никогда не нравились и я их использую редко, потому как они могут быть отключены вообще, и что тогда увидит пользователь?

Остается тогда только тот ваш пример, что вы привели выше. Я его на хосте проверила, все нормально считает.

  Ответить  
 
 автор: sim5   (06.07.2010 в 13:10)   письмо автору
 
   для: Лена   (06.07.2010 в 12:43)
 

И эдак не так, и так не эдак, не угодишь на вас никак. Но, "как только к пользователю на страницу кто-то зайдет, в базу придется делать запрос, чтобы узнать часовой пояс.", в любом случае, если кто-то заходит, то делать надо запрос, формировать страницу...
Или я уже стал сомневаться, что понял вас верно. У вас что все время, которое отображается на сайте, это локальное время сервера, и только единственное время "время последнего посещения", это локальное время пользователя?

PS. У жителей Мьянмы, Урюпинска и Берлина, шансы попасть на ваш сайт одинаковы. )

  Ответить  
 
 автор: Лена   (06.07.2010 в 14:53)   письмо автору
 
   для: sim5   (06.07.2010 в 13:10)
 

>И эдак не так, и так не эдак, не угодишь на вас никак.

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

>У вас что все время, которое отображается на сайте, это локальное время сервера, и только >единственное время "время последнего посещения", это локальное время пользователя?

Да, сейчас у меня так.

  Ответить  
 
 автор: sim5   (06.07.2010 в 16:44)   письмо автору
 
   для: Лена   (06.07.2010 в 14:53)
 

Я то думал, что каждый клиент видит все на сайте этом в рамках своего локального времени. Если же надо отобразить только время последнего посещения как локальное время пользователя (хотя я и не понимаю зачем), то необходимости получать от клиента что либо нет. Нужно отдавать время сервера клиенту, а из него получать время клиента, например:
<?
$time_server 
strtotime('2010-07-06 19:45:46')*1000;
?>
<script>
var dt = new Date(<? echo $time_server?>); 
document.write(dt.getFullYear()+'-'+(dt.getMonth()+1)+'-'+dt.getDate()+
' '+dt.getHours()+':'+dt.getMinutes()+':'+dt.getSeconds());
</script>

И еще кое что о времени.

  Ответить  
 
 автор: Лена   (07.07.2010 в 00:19)   письмо автору
 
   для: sim5   (06.07.2010 в 16:44)
 

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

  Ответить  
 
 автор: sim5   (07.07.2010 в 08:32)   письмо автору
 
   для: Лена   (07.07.2010 в 00:19)
 

Тогда да, запрос смещения, но если запросы на сайте не через индексный файл, то каждый url сайта (файл скрипта) должен предполагать получение смещения. Вот это и не удобно, если не хранить это значение на сервере.

  Ответить  
 
 автор: Trianon   (06.07.2010 в 13:45)   письмо автору
 
   для: Лена   (06.07.2010 в 12:43)
 

>>но есть смещения и 3:30 и 9:30. То есть, совсем не обязательно получать время смещения от клиента деленное на 60 минут
>
>я делаю для немцев и эмигрантов. Маловероятно, что на сайт придет какой-то житель Мьянмы или Афганистана, где смещение по полчаса.
"Маловероятно" это термин, которым программист оперировать не должен.
Применительно к поведению внешней среды.

  Ответить  
 
 автор: Лена   (06.07.2010 в 14:57)   письмо автору
 
   для: Trianon   (06.07.2010 в 13:45)
 

Ок, учту.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования