-
Notifications
You must be signed in to change notification settings - Fork 53
/
serverDate.js
54 lines (44 loc) · 1.47 KB
/
serverDate.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
export const fetchSampleImplementation = async () => {
const requestDate = new Date();
const { headers, ok, statusText } = await fetch(window.location, {
cache: `no-store`,
method: `HEAD`,
});
if (!ok) {
throw new Error(`Bad date sample from server: ${statusText}`);
}
return {
requestDate,
responseDate: new Date(),
serverDate: new Date(headers.get(`Date`)),
};
};
export const getServerDate = async (
{ fetchSample } = { fetchSample: fetchSampleImplementation }
) => {
let best = { uncertainty: Number.MAX_VALUE };
// Fetch 10 samples to increase the chance of getting one with low
// uncertainty.
for (let index = 0; index < 10; index++) {
try {
const { requestDate, responseDate, serverDate } = await fetchSample();
// We don't get milliseconds back from the Date header so there's
// uncertainty of at least half a second in either direction.
const uncertainty = (responseDate - requestDate) / 2 + 500;
if (uncertainty < best.uncertainty) {
const date = new Date(serverDate.getTime() + 500);
best = {
date,
offset: date - responseDate,
uncertainty,
};
}
} catch (exception) {
console.warn(exception);
}
}
return best;
};