Skip to content

Instantly share code, notes, and snippets.

@xPaw
Created March 11, 2025 18:24
Show Gist options
  • Save xPaw/a00dd6d3bb1b53643996bf55647ce1ca to your computer and use it in GitHub Desktop.
Save xPaw/a00dd6d3bb1b53643996bf55647ce1ca to your computer and use it in GitHub Desktop.
function syncTime() {
const startTime = performance.now();
const xhr = new XMLHttpRequest();
xhr.open("GET", "/cdn-cgi/trace", true);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
const endTime = performance.now();
const clientTimestamp = Date.now();
// Get the date from the cloudflare response
const match = xhr.responseText.match(/^ts=([0-9\.]+)/m);
if (!match) {
console.error("Unable to get remote time");
return;
}
const serverTimestamp = Number.parseFloat(match[1]) * 1000;
console.log("Client time:", clientTimestamp);
console.log("Server time:", serverTimestamp);
// Find the resource timing entry for our request
const entry = performance
.getEntriesByType("resource")
.find((entry) => entry.name.endsWith("/cdn-cgi/trace") && entry.startTime >= startTime);
// Calculate time offset
if (entry) {
// When we received the response headers is when the server timestamp was generated
// So we need to adjust the current time by the amount of time that has passed since then
const timeSinceResponse = endTime - entry.responseStart;
// Client time when response headers were received
const clientTimeAtResponse = clientTimestamp - timeSinceResponse;
// Offset is difference between server time and client time at that moment
g_TimeOffset = Math.floor(serverTimestamp - clientTimeAtResponse);
console.log("Request time:", entry.responseStart - entry.requestStart);
console.log("Time to response start:", entry.responseStart - entry.startTime);
console.log("Time for response:", timeSinceResponse);
} else {
const roundTripTime = endTime - startTime;
// Estimate that the server timestamp was captured halfway through the request
// This is more accurate than assuming fixed travel times in both directions
const estimatedCurrentServerTime = serverTimestamp + roundTripTime / 2;
g_TimeOffset = Math.floor(estimatedCurrentServerTime - clientTimestamp);
}
console.log("Offset:", g_TimeOffset);
console.log("Corrected time:", clientTimestamp + g_TimeOffset);
console.log("Sanity check:", clientTimestamp + g_TimeOffset - serverTimestamp);
}
};
xhr.send();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment