Автор: AdamHasker 9.1.2015, 19:41
Можно ли с NTP сервера получить время UTC в миллисекундах. Например так, как это сделано здесь www.windowsfaq_ru/serv/directtime/track.php?id=time_utc
Я спрашиваю не только о вашем сервере, а вообще. Есть ли стандарт для этой темы?
Спасибо.
Автор: AdamHasker 9.1.2015, 19:42
Цитата(AdamHasker @ 9.1.2015, 19:41)
www.windowsfaq_ru/serv/directtime/track.php?id=time_utc
Извините, так как форум не разрешил разместить ссылку, то пришлось её «спрятать».
Автор: Admin 9.1.2015, 20:28
То что Вы предоставили по ссылке - есть обычный Unix Timestamp (с миллисекундами). NTP-сервер же передает время (временной штамп) в своем своем особом формате, согласно описанию протокола формат такой:
Цитата(http://www.opennet.ru/docs/RUS/inet_book/4/44/ntp_4415.html)
Временные метки NTP представляют собой 64-битные числа с фиксированной запятой без знака, которое указывает число секунд с нуля часов 1-го января 1900 года. Целая часть содержит первые 32 разряда, а дробная часть остальные 32 разряда.
Получить сам штамп можно обратившись к NTP-серверу в соответствии с протоколом. В зависимости от Вашего ПО, реализация может быть разная.
Далее полученный штамп необходимо будет конвертировать в Unix Timestamp. Для этого можно применить формулу:
UT = (TS / 1000) - 2208988800.
Ранее для реализации часов на сайте ntp-servers.net мы поступали проще. Наш скрипт обращался к NTP-серверу используя стандартную команду
ntpq -crv, и затем обрабатывал ее вывод (смотрел значение переменной
clock) и получал текущее время, которое преобразовывалось в Unix Timestamp через php-функцию
strtotime() и передавалось в JavaScript.
Скорее всего у windowsfaq все сделано аналогичным образом, либо они используют библиотеку для прямой работы с NTP, например такую: https://github.com/majetzx/ntplite.
Данная библиотека позволяет получать время с NTP-сервера в виде Unix Timestamp (с миллисекундами) таким образом:
Код
<?php
require_once 'NTPLite.php';
$server = 'ntp1.stratum2.ru';
$timestamp = 0;
if ($socket = @stream_socket_client('udp://'.$server.':123', $errno, $errstr, 3))
{
$ntp = new NTPLite(FALSE);
$ntp->versionNumber = 3;
$ntp->mode = 3;
fwrite($socket, $ntp->writeMessage());
if ($ntp->readMessage(fread($socket, 1500)))
{
$timestamp = floor((($ntp->transmitTimestamp / 1000) -
NTPLite::SNTP_TO_UNIX_TS_INTERVAL) * 1000);
}
fclose($socket);
}
echo 'Timestamp: '.$timestamp;
?>
Автор: AdamHasker 9.1.2015, 20:42
Цитата(Admin @ 9.1.2015, 20:28)
Спасибо за исчерпывающий ответ.
Увы, но PHP для моих целей не пригоден. Так что… Буду изобретать велосипед.
Ещё раз — спасибо.