You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

每周重复倒计时定时器问题:需设置为每周四晚8点PST

每周四PST晚8点重复倒计时修复方案

需求是实现每周四太平洋标准时间(PST)晚8点触发重复的倒计时,但现有代码仅在每周五午夜重复,调整变量后计时无变化。

原代码

function CountDown(id, day, time) {

function update() {

    // Get current date and time
    var today = new Date();

    // Get number of days to Friday
    var dayNum = today.getDay();
    var daysToFri = day - (dayNum < day ? dayNum : dayNum - 7);

    // Get milliseconds to noon friday
    var fridayNoon = new Date(+today);
    fridayNoon.setDate(fridayNoon.getDate() + daysToFri);
    fridayNoon.setHours(
        time.split(':')[0],
        time.split(':')[1],
        time.split(':')[2],
        time.split(':')[3]
    );
    // Round up ms remaining so seconds remaining matches clock
    var ms = Math.ceil((fridayNoon - today) / 1000) * 1000;
    var d = ms / 8.64e7 | 0;
    var h = (ms % 8.64e7) / 3.6e6 | 0;
    var m = (ms % 3.6e6) / 6e4 | 0;
    var s = (ms % 6e4) / 1e3 | 0;

    // Display the result in the element with id="demo"
    // document.getElementById(id).innerHTML = d   , h  , m  , s ;style='display:flex; flex-direction:column;'
    // document.getElementById(id).innerHTML = h;
    d = d<10? "0"+d: d;
    h = h<10? "0"+h: h;
    m = m<10? "0"+m: m;
    s = s<10? "0"+s: s;
    document.getElementById(id).innerHTML =  "<div class='clabel'> <p class='countertext'> DAYS </p><h1 class='cnumber days' > " +  d + "</h1></div>" + "<div class='clabel'> <p class='countertext'>HOURS</p><h1 class='cnumber hours'>"+ h +"</h1></div>" + "<div class='clabel'> <P class='countertext'>MINUTES</P><h1 class='cnumber'>"+ m +"</h1></div>"  + "<div class='clabel'><P class='countertext'>SECONDS</p><h1 class='cnumber'>"+ s +"</h1></div>";
    // document.getElementById(id).innerHTML =  "<span  class='c-name'><strong>DAYS</strong></span> " + "<h1 style='font-size:10rem; '>"+ d +"</h1>" + "<span  class='c-name'> <strong>HOURS</strong></span> "
    // + "<h1 style='font-size:10rem;'>"+ h +"</h1>" + "<span class='c-name'> <strong>MINUTES</strong></span> " + "<h1 style='font-size:10rem;'>"+ m +"</h1>" +"<span class='c-name'> <strong>SECONDS</strong></span> " + "<h1 style='font-size:10rem;'>"+ s +"</h1>";

}

// Run update just after next full second
function runUpdate() {
    update();
    setTimeout(runUpdate, 1020 - (Date.now() % 1000));
}

runUpdate();
}

问题根源

  1. 时区未适配:原代码直接使用本地时间计算,未转换到PST,导致目标时间与需求偏差。
  2. 日期计算逻辑错误:daysToFri的逻辑是针对周五设计的,且判断条件有漏洞,无法正确计算到下一个周四的天数。
  3. 时间参数依赖风险:依赖外部传入time参数,若调用时参数错误(比如传入午夜时间),会直接导致倒计时目标错误。

修复后的代码

function CountDown(id) {
    function update() {
        // 获取当前UTC时间,转换为PST(UTC-8,无夏令时)
        const now = new Date();
        const pstNow = new Date(now.getTime() - 8 * 60 * 60 * 1000);
        
        // PST星期几:0=周日,4=周四
        const currentDay = pstNow.getUTCDay();
        let daysToThu;

        // 计算到下一个周四的天数
        if (currentDay < 4) {
            daysToThu = 4 - currentDay;
        } else if (currentDay === 4) {
            // 周四当天,判断是否已过20点
            daysToThu = pstNow.getUTCHours() >= 20 ? 7 : 0;
        } else {
            daysToThu = 7 - (currentDay - 4);
        }

        // 构建目标时间:PST周四20点 = UTC周五4点
        const targetUtc = new Date(pstNow);
        targetUtc.setUTCDate(targetUtc.getUTCDate() + daysToThu);
        targetUtc.setUTCHours(4, 0, 0, 0);

        // 计算时间差,若已过目标时间则自动取下周
        let msDiff = targetUtc.getTime() - now.getTime();
        if (msDiff <= 0) {
            targetUtc.setUTCDate(targetUtc.getUTCDate() + 7);
            msDiff = targetUtc.getTime() - now.getTime();
        }

        // 计算天、时、分、秒
        const ms = Math.ceil(msDiff / 1000) * 1000;
        const d = Math.floor(ms / 8.64e7);
        const h = Math.floor((ms % 8.64e7) / 3.6e6);
        const m = Math.floor((ms % 3.6e6) / 6e4);
        const s = Math.floor((ms % 6e4) / 1e3);

        // 格式化两位数字
        const format = num => num < 10 ? `0${num}` : num;

        // 更新倒计时显示
        document.getElementById(id).innerHTML = `
            <div class='clabel'> 
                <p class='countertext'>DAYS</p>
                <h1 class='cnumber days'>${format(d)}</h1>
            </div>
            <div class='clabel'> 
                <p class='countertext'>HOURS</p>
                <h1 class='cnumber hours'>${format(h)}</h1>
            </div>
            <div class='clabel'> 
                <p class='countertext'>MINUTES</p>
                <h1 class='cnumber'>${format(m)}</h1>
            </div>
            <div class='clabel'>
                <p class='countertext'>SECONDS</p>
                <h1 class='cnumber'>${format(s)}</h1>
            </div>
        `;
    }

    // 对齐整秒更新,避免跳变
    function runUpdate() {
        update();
        setTimeout(runUpdate, 1020 - (Date.now() % 1000));
    }

    runUpdate();
}

// 调用示例:传入倒计时容器的ID
// CountDown('your-timer-element-id');

关键修改说明

  • 时区精准计算:通过UTC时间转换为PST,确保所有逻辑基于目标时区,不受用户本地时区影响。
  • 日期逻辑修复:重新编写了到下一个周四的天数计算逻辑,覆盖了“周四当天未过20点”“周四当天已过20点”“其他日期”三种场景。
  • 时间固定化:直接在代码中固定PST晚8点对应的UTC时间,避免外部参数错误导致的问题。
  • 边界处理:添加了已过目标时间时自动切换到下周的逻辑,确保倒计时始终指向最近的周四晚8点。
  • 代码优化:使用模板字符串简化DOM拼接,新增数字格式化函数提升代码可读性。

内容的提问来源于stack exchange,提问作者VisualExstasy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 22:54:34