Categories: PHPTips

NTP: Consultar la hora

El protocolo NTP provee de un servicio de hora a través de Internet. Resumiendo mucho se trata de poder consultar la hora desde los relojes atómicos dispersos por el mundo y que marcan la hora exacta para todo el mundo.

Cualquier ordenador puede actuar como servidor de hora para otros ordenadores, y se disponen de servidores de hora públicos que dan un servicio muy confiable. En ntp.org podemos encontrar toda la información.

Para poder consultar la hora mediante NTP en PHP no existe ninguna librería, por lo que hay que recurrir a clases o funciones. Mirando por aquí y por allá lo que he visto no funcionaba, así que he creado la siguiente función:

function ntp_time ($host) {
  $msg = hex2bin('e30004fa000100000001000000000000000000000000000000000000000000000000000000000000');
  $data = false;
  if ($sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) {
    if (@socket_connect($sock, $host, 123)) {
      list($xmt['time2'], $xmt['time1']) = explode(' ', microtime());
      $xmt['time1'] += 2208988800;
      $xmt['time2'] *= 4294967296;
      $msg .= pack('N*', $xmt['time1'], $xmt['time2']);
      if (@socket_write($sock, $msg)) {
        if ($recv = @socket_read($sock, 48)) {
          $data = unpack('H2ntp.flags/C1ntp.stratum/C1ntp.ppoll/c1ntp.precision/N1ntp.rootdelay/N1ntp.rootdispersion/H8ntp.refid/N2ntp.reftime/N2ntp.org/N2ntp.rec/N2ntp.xmt', $recv);
          $data['hex'] = bin2hex($recv);
          $data['ntp.rootdelay'] = $data['ntp.rootdelay'] / pow(2, 16);
          $data['ntp.rootdispersion'] = $data['ntp.rootdispersion'] / pow(2, 16);
          $data['ntp.refid'] = implode('.', unpack('C*', hex2bin($data['ntp.refid'])));
          $data['ntp.reftime1'] = sprintf('%u', $data['ntp.reftime1']) - 2208988800;
          $data['ntp.reftime2'] = floor(1000000 * (sprintf('%u', $data['ntp.reftime2']) / pow(2, 32))) / 1000000;
          $data['ntp.org1'] = sprintf('%u', $data['ntp.org1']) - 2208988800;
          $data['ntp.org2'] = floor(1000000 * (sprintf('%u', $data['ntp.org2']) / pow(2, 32))) / 1000000;
          $data['ntp.rec1'] = sprintf('%u', $data['ntp.rec1']) - 2208988800;
          $data['ntp.rec2'] = floor(1000000 * (sprintf('%u', $data['ntp.rec2']) / pow(2, 32))) / 1000000;
          $data['ntp.xmt1'] = sprintf('%u', $data['ntp.xmt1']) - 2208988800;
          $data['ntp.xmt2'] = floor(1000000 * (sprintf('%u', $data['ntp.xmt2']) / pow(2, 32))) / 1000000;
        }
      }
    }
  }

  if (!empty($sock)) socket_close($sock);

  if ($data === false) {
    $err_nbr = socket_last_error();
    if (!empty($sock)) $err_nbr = socket_last_error($sock);
    $err_msg = socket_strerror($err_nbr);
    echo $err_nbr, ' - ', $err_msg, "n";
  }

  return $data;
}
alpha

Share
Published by
alpha
Tags: NTPPHP

Recent Posts

Apuntes de electrónica: Condensador y Bobina en alterna

Hace ya tiempo de mi última entrada de apuntes de electrónica. Fue la entrada sobre…

3 years ago

Review: Zoyi ZT-300AB Multimeter

Looking for cheap multimeters I found the Zoyi ZT-300AB, for about €20 we have a…

3 years ago

Zoyi multimeters, courtesy of Zotek Instruments

In my search for interesting multimeters I came across a manufacturer whose multimeters were sold…

3 years ago

Los productos remarcados

Desde que la industria empezó a deslocalizar sus fabricas llevando gran parte del peso de…

3 years ago

Análisis: Pinza amperimétrica Mestek CM83C

Desde que vi por primera vez una pinza amperimétrica quise tener una. Con la aparición…

3 years ago

Silencio

De lejos nos agobia, la distancia se hace notar con el silencio, de cerca es…

3 years ago