JavaScript进度条时间差百分比计算异常:超100%问题排查求助
问题:进度条百分比超过100%的异常情况
我正在开发一个基于时间差百分比展示的进度条,但遇到了问题:当起始日期为今日、过期日期为明日时,计算出的百分比会超过100%,这不符合预期。以下是我的代码,恳请帮忙检查和评审,任何反馈都将不胜感激,谢谢。
export default function TrackBar({ storageDate, expiryDate }) { // 转换日期为时间戳(毫秒级) function epoch(date) { return Date.parse(date) } // 起始日期转时间戳 const storageTimestamp = epoch(storageDate) // 过期日期转时间戳 const expiryTimestamp = epoch(expiryDate) // 当前日期转时间戳 const dateToday = new Date() const todayTimestamp = epoch(dateToday) const progress = Math.floor((todayTimestamp - storageTimestamp)/(expiryTimestamp - storageTimestamp)* 100) console.log(progress) let color = "#CF5C5C"; if (progress <= 25) { color = "#158463"; } else if (progress <= 50) { color = "#158463" } else if (progress <= 75) { color = "#FD9345" } else if (progress <= 100) { color = "#CF5C5C" } const progressStyles = { width: `${progress}%`, backgroundColor: `${color}`, }; if (!progress){ return ( <h1>Loading......</h1> ) } return ( <> <div className="trackBar"> <div className="trackBar__inner" style={progressStyles}></div> </div> </> ) }
问题分析与修复方案
1. 核心问题:未限制进度范围
当当前时间超过过期时间时,todayTimestamp - storageTimestamp会大于expiryTimestamp - storageTimestamp,导致计算出的progress超过100。即使起始日期是今日、过期日期是明日,只要当前时间走到明日,就会触发这个问题。
2. 修复步骤
(1)强制限制进度在0-100之间
修改progress的计算逻辑,用Math.min和Math.max把值限定在合理范围内:
const progress = Math.floor( Math.min( Math.max( ((todayTimestamp - storageTimestamp) / (expiryTimestamp - storageTimestamp)) * 100, 0 ), 100 ) );
(2)处理无效日期边界
如果过期日期不晚于起始日期(比如传参错误),分母会为负数或0,导致计算异常。需要提前判断并处理:
let progress = 0; if (expiryTimestamp > storageTimestamp) { progress = Math.floor( Math.min( Math.max( ((todayTimestamp - storageTimestamp) / (expiryTimestamp - storageTimestamp)) * 100, 0 ), 100 ) ); } else { // 过期日期早于等于起始日期,直接标记为100%(已过期) progress = 100; }
(3)优化颜色判断逻辑
原代码中<=25和<=50的颜色重复,可以合并条件减少冗余:
let color = "#CF5C5C"; if (progress <= 50) { color = "#158463"; } else if (progress <= 75) { color = "#FD9345"; } // 剩余情况(76%-100%)使用默认红色
(4)修正Loading判断逻辑
原代码中if (!progress)会在进度为0时也显示Loading,这是错误的。应该判断日期是否有效(是否转换为合法时间戳):
if (isNaN(storageTimestamp) || isNaN(expiryTimestamp)) { return <h1>Loading......</h1>; }
修复后的完整代码
export default function TrackBar({ storageDate, expiryDate }) { // 转换日期为时间戳(毫秒级) function epoch(date) { return Date.parse(date) } // 起始日期转时间戳 const storageTimestamp = epoch(storageDate) // 过期日期转时间戳 const expiryTimestamp = epoch(expiryDate) // 当前日期转时间戳 const dateToday = new Date() const todayTimestamp = epoch(dateToday) let progress = 0; if (expiryTimestamp > storageTimestamp) { progress = Math.floor( Math.min( Math.max( ((todayTimestamp - storageTimestamp) / (expiryTimestamp - storageTimestamp)) * 100, 0 ), 100 ) ); } else { progress = 100; } console.log(progress) let color = "#CF5C5C"; if (progress <= 50) { color = "#158463"; } else if (progress <= 75) { color = "#FD9345"; } const progressStyles = { width: `${progress}%`, backgroundColor: `${color}`, }; if (isNaN(storageTimestamp) || isNaN(expiryTimestamp)) { return <h1>Loading......</h1>; } return ( <> <div className="trackBar"> <div className="trackBar__inner" style={progressStyles}></div> </div> </> ) }
内容的提问来源于stack exchange,提问作者user19662721
相关产品推荐
相关产品推荐

