create-react-app实现圣诞倒计时当日提示及到期自动重置
实现方案
核心改三个部分即可满足需求,不需要额外引入依赖:
- 替换写死的固定时间戳,改为动态计算当年/下一年圣诞节的时间戳
- 新增日期状态判断,区分「倒计时中」「圣诞节当日」「已过圣诞节需切换到下一年」三个场景
- 调整渲染逻辑,根据状态切换展示内容
具体修改步骤
1. 新增动态生成圣诞时间戳的工具方法
去掉原来硬编码的const countdownTimeStamp = 1671919200000;,替换为可自动判断年份的时间戳生成函数,所有时间计算统一对齐你使用的Europe/Helsinki时区:
// 自动获取对应年份的圣诞节0点时间戳(赫尔辛基时区) const getChristmasTimestamp = () => { const now = dayJs().tz("Europe/Helsinki"); const currentYear = now.year(); // 当年圣诞节:12月25日0点 const thisYearChristmas = dayJs.tz(`${currentYear}-12-25 00:00:00`, "Europe/Helsinki"); // 次年圣诞节 const nextYearChristmas = dayJs.tz(`${currentYear + 1}-12-25 00:00:00`, "Europe/Helsinki"); // 12月26日0点,作为切换下一年倒计时的分界点 const dayAfterThisChristmas = thisYearChristmas.add(1, "day"); return now.isAfter(dayAfterThisChristmas) ? nextYearChristmas.valueOf() : thisYearChristmas.valueOf(); };
2. 调整状态与时间计算逻辑
把圣诞时间戳存入组件状态,新增圣诞节当日标记,修改剩余时间计算的判断规则:
const Countdown = () => { const [remainingTime, setRemainingTime] = useState(defaultRemainingTime); // 初始值取动态计算的当年圣诞时间戳 const [countdownTimeStamp, setCountdownTimeStamp] = useState(getChristmasTimestamp()); // 标记是否为圣诞节当日 const [isChristmasToday, setIsChristmasToday] = useState(false); const getRemainingTime = (targetTimestamp) => { const targetDayJs = dayJs(targetTimestamp).tz("Europe/Helsinki"); const nowDayJs = dayJs().tz("Europe/Helsinki"); const dayAfterChristmas = targetDayJs.add(1, "day"); // 当前日期为圣诞节当日:设置标记,返回默认时间 if (nowDayJs.isSame(targetDayJs, "day")) { setIsChristmasToday(true); return defaultRemainingTime; } setIsChristmasToday(false); // 当前时间已过12月26日0点:自动更新时间戳为下一年圣诞 if (nowDayJs.isAfter(dayAfterChristmas)) { setCountdownTimeStamp(getChristmasTimestamp()); return defaultRemainingTime; } return { seconds: getRemainingSeconds(nowDayJs, targetDayJs), minutes: getRemainingMinutes(nowDayJs, targetDayJs), hours: getRemainingHours(nowDayJs, targetDayJs), days: getRemainingDays(nowDayJs, targetDayJs), }; }; // 其余工具函数(getRemainingSeconds/padWithZeros等)保持原有逻辑不变 // ...
注意:原useEffect的依赖数组已经包含countdownTimeStamp,时间戳更新时会自动重启定时器,不需要额外修改。
3. 调整渲染逻辑
根据isChristmasToday状态切换展示内容,圣诞节当日隐藏倒计时,显示提示文案:
return ( <div> {isChristmasToday ? ( <span>Christmas today</span> ) : ( <> <span>{remainingTime.days} </span> <span>days </span> <span>{remainingTime.hours} </span> <span>hours </span> <span>{remainingTime.minutes} </span> <span>minutes </span> <span>{remainingTime.seconds} </span> <span>seconds </span> </> )} </div> );
逻辑说明
- 圣诞节当日判断精确到赫尔辛基时区的自然日,会从12月25日0点持续显示提示到12月26日0点,刚好满24小时
- 每秒执行的时间校验会在日期跨过12月26日0点时自动把目标时间切到下一年圣诞节,不需要手动修改时间戳
- 所有时间计算统一使用指定时区,不会因为用户本地设备时区差异出现显示错误
内容的提问来源于stack exchange,提问作者hung5422
相关产品推荐
相关产品推荐

