NTP: Consultar la hora

      No hay comentarios en 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;
}

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *