Как показать отсчет таймера одинаковым для всех?

Приветствую всех!
Задача: нужен таймер на сайте, который запускается, например, в .js или .php файле вручную. Далее обратный отсчет. И цифры все юзеры, зашедшие на страничку должны видеть одинаково, не зависимо от локального времени.
Сделал так, взял за ориентир время на сервере, выставляю старт, конец таймера в 12:00:00, получаю разницу между временем сервера и окончанием в секундах, и добавляю эту разницу к времени клиента. Затем в js делаю уменьшение оставшегося времени каждую секунду.

Проблема в том, что страница грузится у всех по разному, и есть погрешность в 1-3 секунды у людей. Думал как то записывать в бд, но не могу придумать логику
В общем суть в том, что если таймер кончается в 12:00:00 по мск, чтоб все видели сколько осталось, одинаковые цифры, независимо от часового пояса и локального времени на компе.
  • Вопрос задан
  • 2312 просмотров
Решения вопроса 1
sergiks
@sergiks Куратор тега PHP
♬♬
Нужно, чтобы клиент максимально точно «знал», сколько сейчас времени на сервере. Для этого можно несколько раз послать запрос на сервер, и предположить, что время ответа сервера лежит точно посередине между отправкой запроса и получением ответа. Примерно так работает NTP – протокол сетевого времени.

Второе предположение, что ход собственных часов точен: 1 секунда на клиенте и на сервере точно равны.

На сервере разместить простейший скрипт, который возвращает время с миллисекундами до События:
// getTimeTill.php
$deadline = strtotime("2017-07-01 03:00:00");
echo round( 1000 * $deadline - 1000 * microtime(true)); // в миллисекундах

На клиенте в JS надо засечь время, выполнить ajax запрос, получить ответ, и считать, что полученное число микросекунд оставалось до события половину разницы назад:
var start = (new Date).getTime();
$.get("getTimeTill.php", function( ms ){
  var bias = Math.round(((new Date).getTime() - start) / 2);
  var remains = ms + bias; // сколько остаётся микросекунд до события на данный момент
  var deadline = (new Date).getTime() + remains; // локальное время События
  // можно запускать таймер, который раз в 200 ms будет обновлять время до События
  var el = document.getElementById("timer");
  window.setInterval( function(){
    var remains = Math.floor((deadline - (new Date).getTime())/1000);
    var H = Math.floor( remains / 3600);
    remains -= 3600 * H;
    H = ( '0' + H ).substr(-2);
    var M = Math.floor( remains / 60);
    remains -= 60 * M;
    M = ( '0' + M ).substr(-2);
    var S = ( '0' + remains ).substr(-2);
    timer.innerText = "" + H + ":" + M + ":" + S;
  }, 200);
});

Такие запросы можно выполнять неоднократно, каждый раз уточняя таймер отсчёта на клиенте.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
toxa82
@toxa82
Та зачем так усложнять, передавайте в JS timestamp (например time()), и делайте таймер обратного отсчета на JS с помощью new Date(milliseconds) ориентируясь на дату окончания. Суть в том что timestamp не привязан к таймзоне и всегда UTC0, а JS Date преобразовывает timestamp в дату+время с учетом часового пояса компа и все будут видеть одинаковое время до окончания.
Ответ написан
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Если тупо делать: Каждые 5-15 секунд, пока открыта страница, ajax-ом спрашивайте сервер: сколько осталось до нуля? И показывайте его на странице.
А в промежутках - пусть интервал между запросами на сервер - считает таймер клиента.
Чем чаще запрос на сервер - тем точнее будет синхронизация.
Мега-синхронно - только web-socket. (но не думаю, что Вам это нужно)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы