基于日期自动更新HTML年份的Vanilla JS优化方案咨询
需求:每年6月1日自动更新网页年份的优化方案
希望在每年6月1日(生日当天)自动更新网页上的年份。当前用Vanilla JS实现了每24小时检查一次日期的逻辑,想咨询更优的无API实现方案,也接受包含数据库与服务器的解决方案。
现有实现代码:
document.addEventListener("DOMContentLoaded", function () { const informationYear = document.getElementById('information-heading-text-year'); // update year function (check every day if its 1st of June and updates the year if true) function updateYear() { const birthdayDate = new Date(2013, 5, 1); let currDate = new Date(); let years = 0; if(currDate.getMonth() === birthdayDate.getMonth() && currDate.getDay() == birthdayDate.getDay()) { years = currDate.getFullYear() - birthdayDate.getFullYear(); informationYear.textContent = `${years}+`; } } // 1 day (86,400,000 milliseconds) const oneDayInterval = 1200; setInterval(updateYear, oneDayInterval); });
一、无API前端优化方案
先指出原有代码的两个核心问题:
- 用
getDay()判断日期是错误的——getDay()返回的是星期几(0=周日,6=周六),应该用getDate()获取当月具体日期(1-31)。 oneDayInterval设为1200ms(2分钟),和注释的“1天”不符,且频繁轮询会浪费浏览器资源。
优化后的方案:
- 页面加载直接显示正确值:打开页面就计算当前是否过了当年6月1日,直接设置年份,不用等定时器。
- 精准定时,避免无效轮询:计算当前时间到下一个6月1日的时间差,用
setTimeout替代setInterval,到点更新后再计算下一年的延迟,循环执行。
优化代码:
document.addEventListener("DOMContentLoaded", function () { const informationYear = document.getElementById('information-heading-text-year'); const birthdayYear = 2013; const birthdayMonth = 5; // 月份从0开始,5代表6月 const birthdayDay = 1; // 计算并设置当前应显示的年份 function setDisplayYear() { const now = new Date(); const currentYear = now.getFullYear(); // 判断今年是否已经过了生日 const hasBirthdayPassed = now.getMonth() > birthdayMonth || (now.getMonth() === birthdayMonth && now.getDate() >= birthdayDay); // 过了生日用当前年份减出生年,没过去则减1 const displayYear = hasBirthdayPassed ? currentYear - birthdayYear : currentYear - birthdayYear - 1; informationYear.textContent = `${displayYear}+`; } // 计算到下一个6月1日的时间差(毫秒) function getNextBirthdayDelay() { const now = new Date(); let nextBirthday = new Date(now.getFullYear(), birthdayMonth, birthdayDay); // 如果今年生日已过,取明年的日期 if (now > nextBirthday) { nextBirthday.setFullYear(nextBirthday.getFullYear() + 1); } return nextBirthday.getTime() - now.getTime(); } // 初始化显示正确年份 setDisplayYear(); // 定时更新:到下一个生日时执行更新,之后继续设置下一年的定时 function scheduleNextUpdate() { const delay = getNextBirthdayDelay(); setTimeout(() => { setDisplayYear(); scheduleNextUpdate(); }, delay); } scheduleNextUpdate(); });
注意:前端方案依赖客户端系统时间,若用户设备时间不准,显示会出错,这是无API方案的固有局限。
二、服务器/数据库方案
若要彻底避免客户端时间影响,可采用服务器端可靠时间源,有以下几种思路:
- 静态站定时构建部署:如果是静态网站,用CI/CD工具配置定时任务,每年6月1日0点自动构建网站,更新页面年份后重新部署,无需数据库,纯自动化流程。
- 服务器端渲染(SSR):每次用户请求页面时,服务器用自身系统时间计算应显示的年份,直接渲染到页面返回给客户端,前端无需任何定时器,打开页面即为正确值。
- 数据库存储+定时更新:在数据库中存储当前显示的年份,用服务器定时任务(如Linux的Cron、Node.js的node-schedule)每年6月1日自动更新该值。前端可通过接口获取,或在SSR时直接读取数据库值渲染。
举个Node.js定时任务的简单示例(依赖node-schedule):
const schedule = require('node-schedule'); const fs = require('fs'); // 每年6月1日0点执行更新 const updateJob = schedule.scheduleJob('0 0 1 6 *', () => { const birthdayYear = 2013; const currentYear = new Date().getFullYear(); const displayYear = currentYear - birthdayYear; // 此处可替换为写入数据库、更新缓存等操作 fs.writeFileSync('year-config.txt', `${displayYear}+`); });
内容的提问来源于stack exchange,提问作者Nikolaa Kolevv
相关产品推荐
相关产品推荐

