有一个目标核定时间:2020/02/25 20:30:00
获取当前的时间:2020/02/25 20:10:00
获取当前客户端本地的时间(但是这个时间客户可以自己修改本地的时间):真实项目中只能做一些参考的工作,不能做严谨的校验;严格校验的情况下,我们需要的时间是从服务器获取的;
let time = new Date();
如何从服务器获取时间,以及存在的问题
1.可以基于ajax向服务器发送请求,服务器返回的信息中,响应头中包含了服务器时间(GMT 格林尼治时间 => 转换为北京时间 new Date([转换的时间]))
2.由于网络传送存在时差,导致客户端接收到的服务器时间和真实时间存在偏差
- 当响应头信息返回(AJAX状态为2的时候),我们即获取到时间即可
- HTTP传输中的HEAD请求方式,就是只获取响应头的信息
<div class="box">
距离抢购时间还剩:
<span id="spanBox">00:16:34</span>
</div>
function queryServerTime() {
return new Promise(resolve => {
let xhr = new XMLHttpRequest;
xhr.open('head', './data.json');
xhr.onreadystatechange = function () {
if (!/^(2|3)\d{2}$/.test(xhr.status)) return;
if (xhr.readyState === 2) {
// 响应头信息已经返回
let time = xhr.getResponseHeader('date');
time = new Date(time);
resolve(time);
}
};
xhr.send();
});
}
async function init() {
let serverTime = await queryServerTime(),
targetTime = new Date('2020/02/25 20:49:30'),
autoTimer = null;
// 计算时间差
function computed() {
let spanTime = targetTime - serverTime;
if (spanTime <= 0) {
// 已经到达我们的抢购时间了
spanBox.innerHTML = `00:00:00`;
clearInterval(autoTimer);
return;
}
let hours = Math.floor(spanTime / (60 * 60 * 1000));
spanTime = spanTime - hours * 60 * 60 * 1000;
let minutes = Math.floor(spanTime / (60 * 1000));
spanTime = spanTime - minutes * 60 * 1000;
let seconds = Math.floor(spanTime / 1000);
hours = hours < 10 ? '0' + hours : hours;
minutes = minutes < 10 ? '0' + minutes : minutes;
seconds = seconds < 10 ? '0' + seconds : seconds;
spanBox.innerHTML = `${hours}:${minutes}:${seconds}`;
}
computed();
// 间隔1S中后重新计算一次
autoTimer = setInterval(async _ => {
// 我们应该重新从服务器获取时间(但是这样有很大延迟和服务器的压力太大了)
// serverTime = await queryServerTime();
// 我们可以基于第一次获取的时间,在原来的基础上,让其自动累加1000MS即可
serverTime = new Date(serverTime.getTime() + 1000);
computed();
}, 1000);
}
init();