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

SetInterval计时不准致考勤系统计时偏慢问题求助

考勤系统计时偏慢问题排查与修复

故障原因

你当前的计时逻辑依赖setInterval每1000毫秒触发一次并将time加1,这种方式存在本质缺陷:

  • setInterval的执行并不精确:浏览器的事件循环会被页面渲染、其他JS任务等占用,导致回调触发延迟,每一次延迟都会累积,长时间运行后计时就会明显慢于真实时间。
  • 计时基于触发次数而非真实时间差:哪怕setInterval偶尔延迟,你依然按"每1次触发=1秒"统计,自然会和真实时长产生偏差。

修复方案

改用时间戳差值计算的方式:记录签到时的精确时间戳,每次更新计时都通过当前时间与起始时间的差值来计算真实时长,彻底摆脱setInterval触发延迟的影响。

修改后的核心逻辑

  1. 用startTimestamp存储签到时的时间戳(毫秒级),替代原来的time变量。
  2. 签到时记录起始时间,签退时清空起始时间。
  3. 每次计时更新时,计算当前时间与起始时间的差值,转换为时分秒格式。

完整修复代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>考勤系统</title>
</head>
<style>
  body {
    background: black;
    color: #fcbe24;
    padding: 0 24px;
    margin: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    font-size: 18px;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  }
  
  button {
    font-size: 25px;
  }
</style>

<body>
  <h1 id="header"></h1>
  <div>
    <button id="start" style="display:block;" onclick="startTimer()">Check-in</button>
    <button id="stop" style="display:none;" onclick="stopTimer()">Check-out</button>
  </div>
  <div id="time"></div>
</body>
<script>
  let startTimestamp = null;
  let timerInterval = null;

  function startTimer() {
    // 记录签到时的精确时间戳
    startTimestamp = new Date().getTime();
    // 清空之前的计时记录
    document.getElementById("time").innerHTML = "00:00:00";
    timerInterval = setInterval(updateTimer, 1000);
    
    document.getElementById('start').style.display = 'none';
    document.getElementById('stop').style.display = 'block';
  }

  function stopTimer() {
    clearInterval(timerInterval);
    startTimestamp = null;
    
    document.getElementById('start').style.display = 'block';
    document.getElementById('stop').style.display = 'none';
  }

  function updateTimer() {
    if (!startTimestamp) return;
    
    // 计算真实已流逝的毫秒数,转换为秒
    const elapsedSeconds = Math.floor((new Date().getTime() - startTimestamp) / 1000);
    
    // 转换为时分秒格式
    const seconds = elapsedSeconds % 60;
    const minutes = Math.floor(elapsedSeconds / 60) % 60;
    const hours = Math.floor(elapsedSeconds / 3600) % 24;
    
    // 补零处理
    const formattedSeconds = seconds < 10 ? `0${seconds}` : seconds;
    const formattedMinutes = minutes < 10 ? `0${minutes}` : minutes;
    const formattedHours = hours < 10 ? `0${hours}` : hours;
    
    // 获取当前时间用于对比
    const currentDate = new Date();
    const currentTime = `${currentDate.getHours()}:${currentDate.getMinutes()}:${currentDate.getSeconds()}`;
    
    // 更新显示(保留原拼接逻辑,也可改为只显示最新计时)
    document.getElementById("time").innerHTML += `<br>${currentTime}, ${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
  }
</script>

</html>

额外优化点

  • 增加了startTimestamp的空值判断,避免异常情况。
  • 简化了时分秒的补零逻辑,使用模板字符串更简洁。
  • 变量名更语义化,timerInterval替代startInterval,逻辑更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:40:08