Перейти к содержимому

Сервис обмена электронных валют

Партнерская программа Kredov

Как сделать часы, которые идут во время просмотра страницы

#11 yury

yury
  • Пользователь
  • 629 сообщений
  • Репутация: 176
0

Отправлено 13 Май 2009 - 03:06

ZiTosS,

Пожалуйста подскажете, как переделать Ваш скрипт, чтоб время для часов бралось не с клиентского компьютера, а с сервера?

т.е. при загрузке страницы берем текущее время с сервера, примерно так, наверно:

var hours=<?php
echo date('H', time() );
?>; //часы
var minutes=<?php
echo date('i', time() );
?>; //минуты
var seconds=<?php
echo date('s', time() );
?>; //секунды
а вот как потом грамотно заставить часы локально "тикать", без рефреша страницы?
  • 0

#12 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 13 Май 2009 - 14:51

yury, Нет. Так не получится. PHP формирует страницу 1 раз и только. Поэтому тут либо Ajax либо использование JavaScript функций для определения серверного времени.
Попробуйте использовать UTC время
<script type="text/javascript">
<!--
function clock() {
	//Блок с часами, div с id="clockdiv"
var block = document.getElementById('clockdiv');

	// Время в данный момент
thistime = new Date();

var hours=thistime.getUTCHours(); //часы по UTC
var minutes=thistime.getUTCMinutes(); //минуты по UTC
var seconds=thistime.getUTCSeconds(); //секунды по UTC

   //Если часы = {0,9} то добавляем "0" перед числом
if (eval(hours) <10) {hours="0"+hours};

   //Если минуты = {0,9} то добавляем "0" перед числом
if (eval(minutes) < 10) {minutes="0"+minutes};

   //Если секунды = {0,9} то добавляем "0" перед числом
if (seconds < 10) {seconds="0"+seconds};

   //Собираем время которое будем выводить
thistime = hours+":"+minutes+":"+seconds;

block.innerHTML = thistime; //Заносим полученное время в блок
var timer = setTimeout("clock()", 500); // Таймер на вызов функции clock() каждые 0.5 секунды
}

// - End of JavaScript - -->
</script>
Хотя я считаю что данный вариант всегда будет возвращать Западноевропейское время(Дублин, Эдинбург, Лиссабон, Лондон), Касабланка, Монровия, не зависимо от времени сервера.

Так же могу предложить вариант... Один раз вы помещаете с сервера переменные часов, минут, секунд. А далее вы просто обрабатываете эти переменные в JavaScript. Например с помощью setInterval с посекундным вызовом.
  • 0

#13 yury

yury
  • Пользователь
  • 629 сообщений
  • Репутация: 176

Отправлено 13 Май 2009 - 15:59

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

конечно, локальные часы могут спешить или отставать и со временем могут заметно уйти от серверного времени, но ИМХО в первом приближении для информационной веб-странички и такой точности достаточно

к сожалению, у меня пока знания JavaScript-а маловато даже для попытки реализации этого алгоритма :)


  • 0

#14 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 13 Май 2009 - 16:09

yury, Да и так можно, но нужно учитывать, что в минуте 60 секунд, в часе 60 минут, и всего 24 часа. Каждую секунды будет выполняться довольно трудоемкий скрипт. Я бы легче сделал на Ajax. Благо есть давно библиотеки, которые позволяют легко и удобно, а к тому же и быстро всё это осуществить. Например jQuery
Алгоритм таков. Пишем PHP-страницу с содержанием:
<?php
echo date("H:i:s");
?>

Затем на Javascript с использованием библиотеки вызываем Ajax запрос к созданному нами файлу, и вернувшийся результат помещаем куда нужно :P

Документация по Jquery отличнейшая, только правда на английском, но разобраться можно...
  • 0

#15 yury

yury
  • Пользователь
  • 629 сообщений
  • Репутация: 176

Отправлено 13 Май 2009 - 16:32

ZiTosS,
злой ты :P
человек просит помощи, потому как слабовато знает Javascript, - ты же в качестве рецепта предлагаешь ему еще Ajax изучить (по докам на английском), про который (в смысле, про Ajax) человек так и вовсе до сей поры и слыхом не слыхивал.

лана, делать нечего, попробую, вдруг резко просветление в уму наступит? :P

PS
честно говоря, не понял примечания про количество секунд, минут, часов и трудоемкость скрипта.
в случае простых (без запроса времени с сервера в начале) динамических часов на JavaScript-е (см скрипт во втором посте этой ветки), это количество и трудоемкость менее страшны?
  • 0

#16 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 13 Май 2009 - 18:40

yury, да нет.. Всё конечно обработается, но иногда возможно сбивание часов, так как, время обработки не будет успевать за время повторения (ежесекундное).

честно говоря, не понял примечания про количество секунд, минут, часов

Я так подумал, что в delta удобнее хранить разницу между временем сервера и клиентским. ДЛя этого достаточно будет создать объект Date в нужном виде.
А в JavaScript есть возможность смещать время.
<script type="text/javascript">
serverMSeconds = Date.parse(Date(<?=date("Y")?>, <?=date("m")?>, <?=date("d")?> ,<?=date("H")?> ,<?=date("i")?> ,<?=date("s")?>));
nowMSeconds = Date.parse(Date());
delta = serverMSeconds - nowMSeconds;

function clocks()
{
   var nowDate = new Date();
   var time = nowDate.parse(Date()) + delta;
   nowDate.setTime(time);
   setInterval(function(){clocks()}, 1000);
}

</script>

Примерно так можно, не проверял, и конечно же код не оптимизирован :P
  • 0

#17 yury

yury
  • Пользователь
  • 629 сообщений
  • Репутация: 176

Отправлено 13 Май 2009 - 19:57

<script type="text/javascript">
serverMSeconds = Date.parse(Date(<?=date("Y")?>, <?=date("m")?>, <?=date("d")?> ,<?=date("H")?> ,<?=date("i")?> ,<?=date("s")?>));
nowMSeconds = Date.parse(Date());
delta = serverMSeconds - nowMSeconds;

function clocks()
{
   var nowDate = new Date();
   var time = nowDate.parse(Date()) + delta;
   nowDate.setTime(time);
   setInterval(function(){clocks()}, 1000);
}

</script>
ZiTosS,

я тут попытался понять, что делает приведенный код

просьба пояснить для чайника
var time = nowDate.parse(Date()) + delta;
   nowDate.setTime(time);
фактически устанавливает новое значение времени на локальном компьютере, приплюсовав к нему delta?

если я не напутал, то последующий рекурсивный вызов clocks()
setInterval(function(){clocks()}, 1000);
через секунду добавит еще одну дельту к локальному времени, а затем еще и еще?

Либо я ниче не понял либо это совсем не то, что хотелось. :P
  • 0

#18 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 13 Май 2009 - 20:33

yury, Да ты прав :P Я тут случайно рекурсию написал, образуется лавинный наплыв вызова функции и происходит подвисание браузера.
Вот переделал, всё работает.
<html>
<head>
<script type="text/javascript">
//Создаём дату сервера и преобразуем её в количество миллисекунд от 1970 года
serverMSeconds = Date.parse(Date(<?=date("Y")?>, <?=date("m")?>, <?=date("d")?> ,<?=date("H")?> ,<?=date("i")?> ,<?=date("s")?>));
//Создаём дату клиента и преобразуем её в количество миллисекунд от 1970 года
nowMSeconds = Date.parse(Date());
delta = serverMSeconds - nowMSeconds; // Переход = Разность в миллисекундах сервера и клиента

function clocks()
{
	var nowDate = new Date(); // создаём объект с текущим значением клиентской даты
	var time = Date.parse(Date()) + delta; // кол-во миллисекунд клиентской даты + переход
	nowDate.setTime(time); // Устанавливаем объекту nowDate время смещённое

	// если часы, минуты, секунды < 10, для правильного отображения добавляем 0 к началу.
	var hours = (nowDate.getHours() < 10) ? "0"+nowDate.getHours() : nowDate.getHours(); //  часы
	var minutes = (nowDate.getMinutes() < 10) ? "0"+nowDate.getMinutes() : nowDate.getMinutes(); //  минуты
	var seconds = (nowDate.getSeconds() < 10) ? "0"+nowDate.getSeconds() : nowDate.getSeconds(); // секунды
	document.getElementById("clocks").innerHTML = hours + ":" + minutes + ":" + seconds;
}

function enterClocks()
{
	clocks(); //вызываем для изначальности
	setInterval(function(){clocks()}, 500); // вызываем каждые полсекунды, для большей точности.
}

</script>
</head>
<body onLoad="enterClocks();">
	<div id="clocks"></div>
</body>
</html>

  • 0

#19 yury

yury
  • Пользователь
  • 629 сообщений
  • Репутация: 176

Отправлено 13 Май 2009 - 21:09

ZiTosS,

Вау! спасибки.
Действительно фунциклирует. :)
Щас конечно пойду спать: одинадцатый час, однако, уже.

Но завтра начну штудировать сперва твой код на предмет использования всяких пока недоступных моему пониманию яваскриптовых конструкций с ".parse" и "setInterval(function(){clocks()}, 500);".

А потом, как обещал, придется Ajax забарывать. :)


  • 0

#20 yury

yury
  • Пользователь
  • 629 сообщений
  • Репутация: 176

Отправлено 15 Май 2009 - 04:22

ZiTosS,
1.
исследование последнего скрипта показало, что работает он все-таки неверно:
по-прежнему показывает локальное время, а не серверное.
Сразу это не заметилось потому как я тестил скрипт через локально установленный Denwer, соответственно разницу во времени между сервером и клиентом смоделировать было проблемно.
Так вот, трассировка переменных показала, что serverMSeconds и nowMSeconds в коде
//Создаём дату сервера и преобразуем её в количество миллисекунд от 1970 года
serverMSeconds = Date.parse(Date(<?=date("Y")?>, <?=date("m")?>, <?=date("d")?> ,<?=date("H")?> ,<?=date("i")?> ,<?=date("s")?>));
//Создаём дату клиента и преобразуем её в количество миллисекунд от 1970 года
nowMSeconds = Date.parse(Date());
получаются одинаковыми вне зависимости от аргументов Date.parse(Date(...)); и, соответственно, delta все время равна нулю со всеми вытекающими.

Дальнейший анализ и эксперименты с кодом показали, что вот такие изменения
//Создаём дату сервера и преобразуем её в количество миллисекунд от 1970 года
serverMSeconds = Date.parse(new Date(<?=date("Y")?>, <?=date("m")?>, <?=date("d")?> ,<?=date("H")?> ,<?=date("i")?> ,<?=date("s")?>));
//Создаём дату клиента и преобразуем её в количество миллисекунд от 1970 года
nowMSeconds = Date.parse(new Date());
вроде исправляют ситуацию и часы таки начинают показывать серверное (а не локальное) время.

Однако, поскольку, по причине явоскриптовой безграмотности, я сам не очень понял, что собственно исправил, :P
просьба еще разок глянуть скрипт на предмет все ли там путем стало или как-то грамотнее нужно поправлять.
И еще просьба чуть подробнее пояснить, что делает Date.parse(new Date()); и что - Date.parse(Date()); ?

2.
Пока писАл, заметил еще одну любопытную деталь.
Вот значения переменных сразу после синхронизации локального времени с сервером
Текущее время: 05:49:41
serverMSeconds=1245030464000
nowMSeconds=1242352064000
delta=2678400000
т.е. откуда ни возьмись, получается разница в 2,678,400 сек, что в точности равно 31 суткам.
Возникает подозрение, что наши скриптовые часы показывают время на месяц вперед. :P
Для часов без даты это как бы не сильно принципиально, но вдруг захочется и дату выводить?
Очевидно, требуется еще и такая поправка:
//Создаём дату сервера и преобразуем её в количество миллисекунд от 1970 года
serverMSeconds = Date.parse(new Date(<?=date("Y")?>, <?=date("m")?>-1, <?=date("d")?> ,<?=date("H")?> ,<?=date("i")?> ,<?=date("s")?>));
//Создаём дату клиента и преобразуем её в количество миллисекунд от 1970 года
nowMSeconds = Date.parse(new Date());

  • 0

robot

robot
  • Пользователь PRO
  • 2 652 сообщений
  • Репутация: 85


Оформление форума – IPBSkins.ru