Questão:
Como você normaliza os carimbos de data e hora do lado do cliente em javascript para usuários cujos relógios do computador interno estão desativados? Observe que estou lidando com o tempo no UTC.
Contexto:
Eu tenho uma instância do AWS ElasticSearch configurada com várias operações em lote e otimizadas ao longo do caminho, tornando os carimbos de data / hora do lado do servidor não confiáveis (já que os dados podem ficar fora de ordem e o pedido é importante). Portanto, preciso tornar meus carimbos de data e hora do cliente mais confiáveis.
Restrições:
Não posso fazer nenhuma solicitação do lado do servidor (preciso manter as solicitações HTTP no mínimo), mas posso incluir um carimbo de data e hora do servidor gerado quando meu javascript é carregado pela primeira vez no cliente.
Tentativa de solução:
Variáveis definidas externamente:
serverTimestamp
- um carimbo de data / hora UTC (em milissegundos), gerado no lado do servidor quando o javascript é carregado.getCookie
- uma função que obtém um valor de cookie para uma determinada chave (ou uma string vazia, se não for encontrada).
As configurações de controle de cache para o arquivo são "public,max-age=300,must-revalidate"
(portanto, 5 minutos).
const getTimestamp = (function() {
// This cookie is set on the `unload` event, and so should be greater than
// the server-side timestamp when set.
/** @type {!number} */
const cookieTimestamp = parseInt(getCookie("timestamp_cookie"), 10) || 0;
// This timestamp _should_ be a maximum of 5 minutes behind on page load
// (cache lasts 5 min for this file).
/** @type {!number} */
const storedTimestamp = cookieTimestamp > serverTimestamp ?
cookieTimestamp : serverTimestamp;
return function () {
/** @type {!number} */
const timestamp = Date.now();
// This timestamp should be, at a *maximum*, 5-6 minutes behind
// (assuming the user doesn't have caching issues)
/** @type {!number} */
const backupTimestamp = storedTimestamp
+ parseFloat(window.performance.now().toFixed(0));
// Now let's check to see if the user's clock is
// either too fast, or too slow:
if (
// Timestamp is smaller than the stored one.
// This means the user's clock is too slow.
timestamp < backupTimestamp
// Timestamp is more than 6 minutes ahead. User's clock is too fast.
// (Using 6 minutes instead of 5 to have 1 minute of padding)
|| (timestamp - backupTimestamp) > 360000
) {
return backupTimestamp;
} else {
// Seems like the user's clock isn't too fast or too slow
// (or just maximum 1 minute fast)
return timestamp;
}
}
})();
Problema com a solução:
Usando a getTimestamp
função acima , a execução (new Date(getTimestamp())).getUTCDate()
está retornando no dia seguinte para alguns usuários e getUTCHours
parece estar em todo lugar em casos extremos. Não consigo diagnosticar o problema sozinho.
fonte
<?php date_default_timezone_set('UTC'); $o = new StdClass; if(isset($_POST['get_time'])){ /* make sure AJAX get_time is set */ $o->time = time(); echo json_encode($o); /* now you have object with time property for javascript AJAX argument */ } ?>
Respostas:
Atenha-se a carimbos de data e hora no lado do cliente - não se preocupe com datas / horas. Armazene o delta entre o lado do servidor e o relógio do cliente. Envie o carimbo de data e hora do cliente e o delta com as mensagens e reconstrua a data / hora no servidor.
Em seguida, você pode tomar decisões sensatas ao lado do servidor sobre como lidar com jitter e saltos na sincronização do relógio.
fonte
Você não deve confiar no cliente por tempo garantido. Seu JavaScript pode ser algo como:
Se estiver usando PHP:
fonte