用Date手动拼接时间格式最可控,因toLocaleTimeString()时区、语言等行为不可预测;需注意getMonth()返回0–11要+1,单数字用padStart(2,'0')补零,星期几用数组映射,年用getFullYear(),避免getYear(),推荐requestAnimationFrame更新时间。

用 Date 获取时间并手动拼接格式最可控
浏览器的 toLocaleTimeString() 看似方便,但时区、语言、12/24小时制等行为不可预测,尤其在中文环境容易出现“上午10:30”或英文缩写。真要自定义格式(比如“2026-08-26 10:50:30”或“星期三 10:50”),必须自己取值拼接。
关键点是:月份从 getMonth() 返回 0–11,必须 +1;单数字补零要用 padStart(2, '0');星期几需映射数组。
-
const d = new Date()每次都取当前时刻,别复用旧对象 - 年用
d.getFullYear(),别用d.getYear()(已废弃且返回1900年起偏移) - 星期中文映射建议:
['星期日','星期一','星期二','星期三','星期四','星期五','星期六'][d.getDay()]
setInterval 每秒更新有精度和内存风险
直接 setInterval(updateTime, 1000) 看似合理,但实际执行间隔可能漂移(如卡顿导致连续两次调用间隔为 1050ms),造成跳秒或重复渲染。更严重的是,页面隐藏后定时器仍在运行,浪费资源。
- 用
document.visibilityState === 'visible'判断页面是否可见,隐藏时clearInterval - 优先考虑
requestAnimationFrame驱动更新:它按屏幕刷新节奏执行,视觉更平滑,且页面后台自动暂停 - 如果坚持用
setInterval,务必保存返回值(如let timerId = setInterval(...)),以便后续清理
12 小时制转换容易漏掉凌晨/中午边界
把 getHours() 转成 12 小时制不是简单 % 12:0 时(午夜)应显示为 12,12 时(正午)也应显示为 12,AM/PM 判定逻辑必须显式写出。
立即学习“前端免费学习笔记(深入)”;
- 小时计算:
const hour12 = h === 0 ? 12 : h > 12 ? h - 12 : h - AM/PM 判定:
const period = h ,注意 0 时属于 AM,12 时属于 PM - 别用
h % 12 || 12这种写法——它会让 0 变成 12(正确),但 12 也变成 0(错误)
时区处理不能只靠 Intl.DateTimeFormat
想显示东京时间或纽约时间,不能靠 new Date() 再手动加减小时——夏令时、闰秒、历史时区变更全会出错。必须用 Intl.DateTimeFormat 的 timeZone 选项,但要注意兼容性。
- 基础写法:
new Intl.DateTimeFormat('zh-CN', { timeZone: 'Asia/Tokyo', hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' }).format(new Date()) - IE 完全不支持
timeZone,若需兼容,得引入moment-timezone或luxon - 服务端传来的 UTC 时间戳,前端用
new Date(timestamp)构造后,再交由Intl格式化,避免本地时区干扰
真实项目里,时间格式往往要同时满足多时区、可配置、低资源占用三个条件。最易被忽略的是页面生命周期管理——没人关定时器,没人处理 visibilitychange,小功能拖垮整个页面性能的情况太常见了。



















