I tried to create a get timestamp function like Date.now()
. I assume that Date.now()
will use the time from the user's computer, so there is no guarantee that the UNIX time is accurate if the user sets the time manually. I would create a function to get a standardized timestamp from the time server API instead, to make sure that the timestamp is the same for all of the users.
function timefromInternet() {
return new Promise((resolve, reject) => {
fetch("http://worldtimeapi.org/api/timezone/Asia/Taipei")
.then(response => response.json())
.then(data => {
resolve(data.unixtime);
}).catch(error => { resolve(Date.now()); });
});
}
but it is too slow, so I could not execute like Date.now()
for example like this:
let callInfo = {
timestamp: Date.now(),
status: "PAUSE",
};
this.$store.commit("setCallInfo", callInfo);
this.$store.commit("updateLocalUserByObject", {
status: callInfo.status,
});
I want to replace Date.now()
with something like this:
let callInfo = {
timestamp: timefromInternet(),
status: "PAUSE",
};
this.$store.commit("setCallInfo", callInfo);
this.$store.commit("updateLocalUserByObject", {
status: callInfo.status,
});
What is the best solution to modify timefromInternet()
so it could be run like Date.now()
? Because if I am using promises, I could not call like Date.now()
above. Thanks in advance.
CodePudding user response:
You can request the time only once at page load and then make your getTimeStamp()
synchronous.
There are a few clock timers available in the browser, some that the users can't easily mess with. For instance performance.now()
will be relative to the page load and will use a monotonic clock which should keep ticking, no matter what the user does with its System Settings (contrarily to Date, which in some UAs always request the system date, not only at page load).
One case where this clock may stop ticking is when the computer goes to sleep. One workaround for that is to make a new request when the page gains focus again.
async function fetchExactDateFromServer() {
const resp = await fetch("https://worldtimeapi.org/api/timezone/Europe/Paris");
if (!resp.ok) {
throw new Error("Network Error");
}
return new Date((await resp.json()).datetime);
}
let offset = 0;
function getTimeStamp() {
return Math.round(performance.now() - offset);
}
function updateTime() {
return fetchExactDateFromServer()
.then((officialTime) => {
offset = performance.now() - officialTime;
})
.catch((err) => {
console.error(err);
return Promise.reject(err);
});
}
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === 'visible') {
updateTime();
}
});
// test by logging the difference between server-side and local (should always be about the same difference)
const btn = document.querySelector("button");
updateTime().then(() => {
btn.onclick = (evt) => console.log(getTimeStamp(), Date.now(), getTimeStamp() - Date.now());
btn.disabled = false;
});
<button disabled>Test</button>
CodePudding user response:
You should trust the system clock. Virtually all modern OSen are running an NTP daemon of some flavour or other.
There's too much stuff these days, Kerberos off the top of my head, and SSL/TLS, that depends on clock synchronicity for them to do otherwise.
About the only exception might be systems in a hardened, air-gapped, environment. And they've probably got an accurate time source of their own (GPS receiver, atomic clock radio, etc.)