每周重复倒计时定时器问题:需设置为每周四晚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(); }
问题根源
- 时区未适配:原代码直接使用本地时间计算,未转换到PST,导致目标时间与需求偏差。
- 日期计算逻辑错误:
daysToFri的逻辑是针对周五设计的,且判断条件有漏洞,无法正确计算到下一个周四的天数。 - 时间参数依赖风险:依赖外部传入
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
相关产品推荐
相关产品推荐

