使用The Final Countdown倒计时插件时如何进行时区调整?
问题根源
- jQuery.countdown插件默认将传入的
Date对象按UTC时间解析,即便你用moment生成了对应时区的Date对象,插件内部的时区逻辑还是会产生1小时偏差 - 代码中使用的moment-timezone版本时区数据仅覆盖到2020年,无法正确读取2021年的时区规则,进一步加剧了时间计算误差
修复方案
1. 更新依赖版本
替换旧的moment-timezone引入,使用包含近10年时区数据的版本,保证2021年的欧洲夏令时/冬令时规则可以正常读取:
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.34/moment-timezone-with-data-10-year-range.min.js"></script>
2. 调整倒计时调用逻辑
直接向插件传入目标时间的时间戳,跳过插件的时区转换环节,从根源避免时区偏差:
function doCountDown(countDownContainer, endTimeStamp) { $(countDownContainer).countdown(endTimeStamp, function(event) { $(this).html(event.strftime('<ul class="list-unstyled clock">' + '<li class="days"><span>%-D</span><span>days</span></li> ' + '<li class="hrs"><span>%H</span><span>hours</span></li> ' + '<li class="mins"><span>%M</span><span>minutes</span></li> ' + '<li class="seconds"><span>%S</span><span>seconds</span></li></ul>')); }); } let deadLine = moment.tz('2021-12-25 00:00:00', 'Europe/Bucharest'); doCountDown('#count_down', deadLine.valueOf());
无moment依赖的原生实现
如果不需要兼容极低版本浏览器,可以直接用原生API处理时区,减少第三方依赖:
// 原生方法获取指定时区的目标时间戳 function getTimeZoneTimeStamp(dateStr, timeZone) { const targetLocalDate = new Date(dateStr); const utcDate = new Date(targetLocalDate.toLocaleString('en-US', { timeZone: 'UTC' })); const tzDate = new Date(targetLocalDate.toLocaleString('en-US', { timeZone })); const offset = utcDate.getTime() - tzDate.getTime(); return targetLocalDate.getTime() + offset; } const deadLine = getTimeZoneTimeStamp('2021-12-25 00:00:00', 'Europe/Bucharest'); doCountDown('#count_down', deadLine);
原理说明
时间戳是UTC时间1970年1月1日到指定时间的毫秒数,本身不存在时区属性。直接传入时间戳后,插件仅需要计算当前时间戳和目标时间戳的差值即可得到准确的倒计时时长,完全规避了不同时区转换带来的误差问题。
内容的提问来源于stack exchange,提问作者Razvan Zamfir
相关产品推荐
相关产品推荐

