Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Обновление даты и времени без отправки запроса (https://javascript.ru/forum/misc/59461-obnovlenie-daty-i-vremeni-bez-otpravki-zaprosa.html)

XCanG 12.11.2015 10:22

Обновление даты и времени без отправки запроса
 
Добрый день. Интересует такой вопрос:
Сервер работает по принципу шаблона, в шаблоне есть переменная %timestamp% показывающая текущее время на сервере, имеет вид: 12.11.2015 12:09:51 (число.месяц.год час:минута:секунда) и переменная %uptime% показывающая время работы сервера 01:43:59 (час:минута:секунда).

При загрузке страницы они показывают текущее время, но на этом останавливаются. Хотелось бы их обновлять без дополнительных запросов к серверу, я уверен это возможно.

Эти переменные в коде шаблона внёс в специальные span с id:
<div id='serverinfo'>
							{.!Время на сервере.}: <span id="time1">%timestamp%</span><br />
							{.!Время работы.}: <span id="time2">%uptime%</span>
						</div>

Ну и начал писать такой скрипт (пока для %timestamp%), однако дописать не могу. Не знаю как можно распознать строку в дату и вероятно сам код написал неправильно до конца.
var tst, t = new Date;
t= 0;
tst = %timestamp%;
var upd_tst = document.getElementById("time1")
function TimstUpd(){
	t=t+1000;
	tst=tst+t;
	upd_tst.innerHTML = tst;
}
window.setInterval("TimstUpd()",1000);

В случае со второй функцией, если часы превысят 24 часа, то можно просто дальше накручивать в часы (48, 60, 100, 200), а не создавать блок под дни, месяцы...

Подскажет кто со скриптом?

рони 12.11.2015 10:48

XCanG,
воспользуйтесь поиском

ksa 12.11.2015 11:26

Цитата:

Сообщение от XCanG
я уверен это возможно

Откуда такая уверенность в синхронизации серверного времени на клиенте? :blink:

laimas 12.11.2015 12:29

Цитата:

Сообщение от ksa
Откуда такая уверенность в синхронизации серверного времени на клиенте?

А синхронизация и не нужна, а показывать время сервера на клиенте не проблема.

ksa 12.11.2015 13:23

Цитата:

Сообщение от laimas
синхронизация и не нужна

Просто так написать "серверное время", а потом показывать что-то похожее? :D

laimas 12.11.2015 13:31

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

ksa 12.11.2015 13:58

Цитата:

Сообщение от laimas
и часы будут тикать по времени сервера

Согласен... :yes:

XCanG 13.11.2015 00:07

Цитата:

Сообщение от рони (Сообщение 395798)
XCanG,
воспользуйтесь поиском

Это всё не то, вы видимо не правильно поняли как у меня оно работает. %timestamp% это не числовое значение, как в других тредах, это просто аналогия, переменная, которая содержит в себе текст. Он НЕ преобразуется скриптом или ещё как. В общем нашёл решение на Stackoverflow и подстроил под себя.

Решение скрипта оказалось таким:
<script type="text/javascript">
								var tst = '%timestamp%';
								var upt = '%uptime%';
								var m = tst.match(/\d+/g);
								var n = upt.match(/\d+/g);
								var dat = new Date(m[2],m[1] - 1,m[0],m[3],m[4],m[5]);
								var rat = new Date(m[2],m[1] - 1,m[0],n[0],n[1],n[2]);
								var t = 0;
								var upd_div = document.getElementById("time1");
								var up2_div = document.getElementById("time2");
								function timeupd(){
									t = t + 1000;
									dat.setSeconds(dat.getSeconds() + 1);
									rat.setSeconds(rat.getSeconds() + 1);
									upd_div.innerHTML = ("0" + dat.getDate()).slice(-2) + "." + ("0"+(dat.getMonth()+1)).slice(-2) + "." + dat.getFullYear() + " " + ("0" + dat.getHours()).slice(-2) + ":" + ("0" + dat.getMinutes()).slice(-2) + ":" + ("0" + dat.getSeconds()).slice(-2);
									up2_div.innerHTML = ("0" + rat.getHours()).slice(-2) + ":" + ("0" + rat.getMinutes()).slice(-2) + ":" + ("0" + rat.getSeconds()).slice(-2);
								}
								window.setInterval("timeupd()",1000);
							</script>

Вот как работает:

рони 13.11.2015 00:20

Цитата:

Сообщение от XCanG
Он НЕ преобразуется скриптом или ещё как.

абалдеть значит ваш скрипт волшебный, если именно это и делает :)
а строки 8 и 12 зачем?

XCanG 13.11.2015 01:11

Цитата:

Сообщение от рони (Сообщение 395943)
абалдеть значит ваш скрипт волшебный, если именно это и делает :)
а строки 8 и 12 зачем?

А, остались от старого скрипта. Они тут не нужны, да.
<script type="text/javascript">
								var tst = '%timestamp%';
								var upt = '%uptime%';
								var m = tst.match(/\d+/g);
								var n = upt.match(/\d+/g);
								var dat = new Date(m[2],m[1] - 1,m[0],m[3],m[4],m[5]);
								var rat = new Date(m[2],m[1] - 1,m[0],n[0],n[1],n[2]);
								var upd_div = document.getElementById("time1");
								var up2_div = document.getElementById("time2");
								function timeupd(){
									dat.setSeconds(dat.getSeconds() + 1);
									rat.setSeconds(rat.getSeconds() + 1);
									upd_div.innerHTML = ("0" + dat.getDate()).slice(-2) + "." + ("0"+(dat.getMonth()+1)).slice(-2) + "." + dat.getFullYear() + " " + ("0" + dat.getHours()).slice(-2) + ":" + ("0" + dat.getMinutes()).slice(-2) + ":" + ("0" + dat.getSeconds()).slice(-2);
									up2_div.innerHTML = ("0" + rat.getHours()).slice(-2) + ":" + ("0" + rat.getMinutes()).slice(-2) + ":" + ("0" + rat.getSeconds()).slice(-2);
								}
								window.setInterval("timeupd()",1000);
							</script>

XCanG 13.11.2015 01:20

Цитата:

Сообщение от рони (Сообщение 395943)
абалдеть значит ваш скрипт волшебный, если именно это и делает :)
а строки 8 и 12 зачем?

Не, ну у всех других в темах timestamp был типа времени в миллисеундах(?) с 1970 года, записанных числом, типо 12334243424. У меня это делалось на стороне программы и в шаблон вставлялась текстовая переменная, в первом посте пример написал. То есть там не вставлялось число, а после вставки переиначивалось в вид даты или ещё как, поэтому у меня был вариант только заного разобрать дату на составляющие (ключевым были методы: .match(/\d+/g); (разбор на части), dat.setSeconds(dat.getSeconds() + 1); (прибавка к Дате, а не к числу, что позволило мне избавиться от алгоритмов с циклами и проверками на переполнение за 60 (секунд/минут), 24 (часа)), ("0" + dat.getDate()).slice(-2)... возвращение частям даты цельный вид (1→01, 2→02). Без знания этих методов у меня не получилось собрать скрипт, а остальное я уже знал)

рони 13.11.2015 01:31

время на сервере без использования new Date
 
XCanG,
строки после 100 для примера ... через некоторое время ваш вариант будет менее точен потому что setInterval и getSeconds() + 1 да и запустится через секунду

<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  .time{
    color: rgb(102, 255, 255);
     background-color: rgb(0, 0, 255);
     padding: 2px 4px;
     border-radius: 4px;
  }

  .time span{
    margin: 2px;
    font-weight: bold;
  }
  .time .sp, .time .spl{
    color: rgb(255, 255, 255);
    font-size: 20px;
  }
  .sec {
    color: rgb(255, 255, 0);
  }

  </style>
</head>

<body>
  <span class="time"></span><br>
  <span class="time"></span><br>
  <span class="time"></span><br>
  <span class="time"></span>
<script>

function fn(f) {
    var b = {
        elem: f,
        cls: ["hour", "sp", "min", "spl", "sec"],
        formatTime: function(a) {
            a = Math.floor(a / 1E3);
            var c = Math.floor(a / 60),
                d = Math.floor(c / 60);
            a %= 60;
            c %= 60;
            return [b.two(d % 24), ":", b.two(c), ":", b.two(a)]
        },
        two: function(a) {
            return (9 < a ? "" : "0") + a
        },
        timer: function(a) {
            var c = performance.now();
            requestAnimationFrame(function g(e) {
                e =  e - c;
                b.fullData = b.formatTime(a.from + e);
                requestAnimationFrame(g)
            })
        }
    };
    b.cls.forEach(function(a, c) {
        var d = document.createElement("span");
        d.classList.add(a);
        f.appendChild(d);
        Object.defineProperty(b, a, {
            get: function() {
                return d.innerHTML
            },
            set: function(a) {
                d.innerHTML = a
            }
        })
    });
    Object.defineProperty(b, "fullData", {
        set: function(a) {
            b.cls.forEach(function(c, d) {
                b[c] = a[d]
            })
        },
        get: function() {
            return b.cls.map(function(a, c) {
                return b[a]
            })
        }
    });
    return b.timer
};
function init(a)
{  a = a.split(':')
   return a[0] * 60 * 60 * 1000 + a[1] * 60 * 1000 + a[2] * 1000
}

var span = document.querySelectorAll('.time') ;
var timer = fn(span[0]);
timer({
        from : init('02:08:41')
    })
timer = fn(span[2]);
timer({
        from : init('07:43:19')
    })


								var tst = '13.11.2015 02:08:41';
								var upt = '07:43:19';
								var m = tst.match(/\d+/g);
								var n = upt.match(/\d+/g);
								var dat = new Date(m[2],m[1] - 1,m[0],m[3],m[4],m[5]);
								var rat = new Date(m[2],m[1] - 1,m[0],n[0],n[1],n[2]);
								var upd_div = span[1];
								var up2_div = span[3];
								function timeupd(){
					   				dat.setSeconds(dat.getSeconds() + 1);
									rat.setSeconds(rat.getSeconds() + 1);
									upd_div.innerHTML = ("0" + dat.getDate()).slice(-2) + "." + ("0"+(dat.getMonth()+1)).slice(-2) + "." + dat.getFullYear() + " " + ("0" + dat.getHours()).slice(-2) + ":" + ("0" + dat.getMinutes()).slice(-2) + ":" + ("0" + dat.getSeconds()).slice(-2);
									up2_div.innerHTML = ("0" + rat.getHours()).slice(-2) + ":" + ("0" + rat.getMinutes()).slice(-2) + ":" + ("0" + rat.getSeconds()).slice(-2);
								}
								window.setInterval("timeupd()",1000);
</script>

</body>
</html>

рони 13.11.2015 02:39

часы по времени сервера
 
:write:
убрал лишнее
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  .time{
    color: rgb(102, 255, 255);
     background-color: rgb(0, 0, 255);
     padding: 2px 4px;
     border-radius: 4px;
  }

  .time span{
    margin: 2px;
    font-weight: bold;
  }
  .time .sp, .time .spl{
    color: rgb(255, 255, 255);
    font-size: 20px;
  }
  .sec {
    color: rgb(255, 255, 0);
  }

  </style>
</head>

<body>
  <span class="time"></span><br>

<script>

function fn(f, a) {
    var c = {
        cls: ["hour", "sp", "min", "spl", "sec"],
        formatTime: function(b) {
            b = Math.floor(b / 1E3);
            var a = Math.floor(b / 60),
                d = Math.floor(a / 60);
            b %= 60;
            a %= 60;
            return [c.two(d % 24), ":", c.two(a), ":", c.two(b)]
        },
        two: function(b) {
            return (9 < b ? "" : "0") + b
        },
        timer: function(b) {
            var a = performance.now();
            requestAnimationFrame(function g(e) {
                e -= a;
                e = c.formatTime(b + e);
                c.cls.forEach(function(a, b) {
                    a.innerHTML = e[b]
                });
                requestAnimationFrame(g)
            })
        },
        init: function() {
            a = a.split(":");
            a = 36E5 * a[0] + 6E4 * a[1] + 1E3 * a[2];
            c.cls = c.cls.map(function(a) {
                var d = document.createElement("span");
                d.classList.add(a);
                f.appendChild(d);
                return d
            });
            c.timer(a)
        }
    };
    c.init()
};


var span = document.querySelector('.time') ;
fn(span, '02:08:41');// fn(span, '%uptime%'); 
//fn(span, '<?php echo date("G").":".date("i").":".date("s"); ?>'); 
</script>

</body>
</html>

laimas 13.11.2015 06:19

Цитата:

Сообщение от XCanG
То есть там не вставлялось число, а после вставки переиначивалось в вид даты или ещё как, поэтому у меня был вариант только заного разобрать дату на составляющие

Все это глупости и бесполезные навороты.

Сервер возвращает смещение часового пояса для временных зон, расположенных западнее UTC как отрицательные числа, а расположенных восточнее UTC - положительные. На клиенте же это смещение для временных зон, расположенных западнее UTC возвращаются положительные числа, а расположенных восточнее UTC - отрицательные.
Остается привести это к одним единицам и сформировать метку по которой и получать текущее время на клиенте скорректированное по времени сервера.

localTime + offset_local + offset_server

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

XCanG 13.11.2015 16:11

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

laimas 13.11.2015 16:26

Цитата:

Сообщение от XCanG
в пределах секунды это не так страшно (особенно если учесь что на некоторых компьютерах даже после синхронизации времени иногда смотришь туда и сюда и время в трее различно на 1 минуту).

Вот только не надо глупостей.

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

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


Часовой пояс GMT +3, время: 16:24.