侧边栏壁纸
博主头像
封存记忆 博主等级

行动起来,活在当下

  • 累计撰写 32 篇文章
  • 累计创建 29 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

js网络时间校对

Administrator
2025-03-11 / 0 评论 / 0 点赞 / 6 阅读 / 0 字

nginx配置

location /{
         add_header Access-Control-Allow-Origin *;
         add_header Access-Control-Allow-Credentials true;
         add_header Access-Control-Expose-Headers "Date";  
         add_header Access-Control-Allow-Methods *;
    }

js配置

my_time.js

export default class MyTime {
    /**
     * 我的定时器
     * @param {number} interval  执行间隔,默认1s
     * @param {function} cb 间隔结束后执行的方法
     * @param {function} cancelCb 判断什么时候结束,返回值是布尔值,返回true则终止。
     * @param {function} afterCancelCb 结束之后执行的函数
     */
    mySetInterval(cb, cancelCb, afterCancelCb, interval = 1000) {
        let timer = null;
        let pre = new Date();
        let fn = function () {
            timer = requestAnimationFrame(() => {
                let cur = new Date();
                if (cur - pre >= (interval-10)) {
                    cb();
                    pre = cur;
                }
                timer = requestAnimationFrame(fn);
                if (cancelCb && cancelCb()) {
                    afterCancelCb();
                    timer && cancelAnimationFrame(timer);
                }
            });
        };
        fn();
    }

    /**
     * 获取网络时间
     * @param {String} url 请求网络时间地址
     * @returns {boolean}
     */
    GetNetDiffTime(url) {
        this.isFixing = true
        let xhr;
        if (window.XMLHttpRequest) {
            xhr = new window.XMLHttpRequest();
        } else { // ie
            xhr = new ActiveObject("Microsoft")
        }
        xhr.open("GET", url + "?t=" + Date.parse(new Date()), false)//false不可变
        try {
            xhr.send(null);
            let date = xhr.getResponseHeader("date");
            if (date !== undefined && date !== "") {
                this.setNetDiffTime(date);
                this.isFixing = false
                return true
            } else {
                console.log("获取网络时间失败", xhr.getAllResponseHeaders())
            }
        } catch (e) {
            console.log("获取网络时间失败", e)
        }
        this.isFixing = false
        return false
    }

    //初始化网络时间差
    initNetDiffTime(url, isThrow) {
        if (!this.GetNetDiffTime(url) && isThrow) {
            this.isDestroy = true
            throw new Error("获取网络时间失败")
        }
        if (!this.isDestroy) {
            setTimeout(() => {
                if (!this.isDestroy) {
                    this.initNetDiffTime(url, false)
                }
            }, 60000)
        }
    }

    /**
     * 格式化时间
     * @param {Date} date
     * @returns {string}
     */
    format(date) {
        const year = date.getFullYear()
        const month = date.getMonth() + 1
        const day = date.getDate()
        const hour = date.getHours()
        const minute = date.getMinutes()
        const second = date.getSeconds()
        return [year, month, day].map((n) => {
            n = n.toString()
            return n[1] ? n : '0' + n
        }).join('/') + ' ' + [hour, minute, second].map((n) => {
            n = n.toString()
            return n[1] ? n : '0' + n
        }).join(':')
    }

    //设置网络时间差
    setNetDiffTime(timeStr) {
        let time= Date.parse(timeStr) / 1000
        this.currentTime=  Date.parse(new Date()) / 1000
        this.diffTime = time- this.currentTime
        return this
    }

    /**
     * 初始化
     * @param {String} url 时间网络地址
     * @param {Boolean} isMust 是否必须初始化网络时间
     * @returns {number|Number|*|undefined|{destroy(): void, setDiffTime(Number): *, getDiffTime(): Number, getTimeStamp(): Number, getDate(): Date, format(Date): string}|string|Date}
     */
    constructor(url, isMust = true) {
        let that = this
        this.diffTime = 0;
        this.isDestroy = false;
        this.isFixing = false
        this.currentTime = Date.parse(new Date()) / 1000;
        this.mySetInterval(
            () => {
                this.currentTime += 1;
                if (!this.isFixing && Math.abs(this.currentTime - Date.parse(new Date()) / 1000) > 1) {
                    setTimeout(() => {
                        this.GetNetDiffTime(url)
                    })
                }
            },
            () => {
                return this.isDestroy;
            },
            () => {
                console.log('结束的时候执行的回调');
            }
        )
        try {
            this.initNetDiffTime(url, isMust)
        } catch (e) {
            return undefined
        }
        return {
            /**
             * 销毁
             */
            destroy() {
                that.isDestroy = true
            },
            /**
             * 设置时间差
             * @param {Number} dt
             * @returns {*}
             */
            setDiffTime(dt) {
                that.diffTime = dt;
                return this
            },
            /**
             * 获取时间差
             * @returns {Number}
             */
            getDiffTime() {
                return that.diffTime;
            },
            /**
             * 获取当前校正后的时间戳  去除1000的
             * @returns {Number}
             */
            getTimeStamp() {
                return that.currentTime + that.diffTime;
            },
            /**
             * 获取矫正后的date时间对象
             * @returns {Date}
             */
            getDate() {
                return new Date(this.getTimeStamp() * 1000);
            },
            /**
             * 格式化时间
             * @param {Date} date
             * @returns {string}
             */
            format(date) {
                return that.format(date)
            }
        };
    }
}

demo测试

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>网络时间校正</title>
</head>
<body>
<p>本机时间:<span id="local_time" style="color: green;"></span></p>
<p>网络时间:<span id="net_time" style="color: green;"></span></p>
</body>
<script type="module">
    import MyTime from './my_time.js?v=1';
    let myTime = new MyTime("http://time.a.hebei9.cn");
    if (myTime === undefined){
        alert("初始化网络时间错误")
    }else{
        window.onload = function () {
            setInterval(function () {
                const localTime = document.getElementById('local_time');
                const netTime = document.getElementById('net_time');
                localTime.innerHTML = myTime.format(new Date());
                netTime.innerHTML = myTime.format(myTime.getDate());
            }, 1000);
        }
    }
</script>
</html>

对比时间站

参考时间站

0

评论区