讲解如何在JavaScript中使用Date对象获取用户设备当前本地时间,分别介绍手动拼接YYYY-MM-DD HH:mm:ss格式与Intl.DateTimeFormat本地化输出,并给出每秒自动刷新页面DOM的完整示例与常见偏差排查。
JavaScript怎么获取并显示当前本地时间
时间:2026-11-13
浏览:439
文章目录
在 JavaScript 中获取当前本地时间,核心只需要一句 new Date()。拿到时间对象后,可以按“提取年月日时分秒并用 padStart 补零”的方式拼出固定格式,也可以交给内置的 Intl.DateTimeFormat 按中文习惯直接格式化,最后把结果写进网页元素的 textContent,再配合 setInterval 每秒重绘一次,就能在页面上做出稳定的本地实时时钟。
先看懂 new Date() 拿到的是什么
刚写时间显示功能时,很多人会在控制台先打印一下 new Date(),或者顺手调用 toISOString(),结果页面上突然多出一段英文缩写,或者时间比电脑右下角正好慢了 8 个小时。这并不是代码算错了,而是 Date 对象内部存储和外部输出采用了两套不同的视角。
在浏览器和 Node.js 运行时中,new Date() 读取的是用户当前设备的系统时钟,并在对象内部只保存一个数字:从协调世界时(UTC)1970 年 1 月 1 日零点到此刻经过的毫秒数。这个数字本身没有时区概念,只有当你调用具体方法把它转成字符串或拆出年、月、日时,它才会决定要不要叠加设备所在的本地时区。
const now = new Date();
console.log(now.toString());
console.log(now.toISOString());
console.log(now.toLocaleString('zh-CN'));
Wed Nov 11 2026 16:13:44 GMT+0800 (中国标准时间) 2026-11-11T08:13:44.000Z 2026/11/11 16:13:44
可以看到,toISOString() 末尾带了一个 Z,代表它强制按 UTC 零时区输出,所以东八区会显示 08:13:44;而 toString() 和 toLocaleString('zh-CN') 才按本地时区换算成了 16:13:44。搞清这条分界线,就不会把零时区字符串误当成本地时间直接展示给读者。
按固定格式显示:提取时间分量并补零
绝大多数网页界面需要的并不是英文长串,而是像 2026-11-11 16:05:09 这样对齐工整的格式。要把 Date 对象拆成这种固定格式,思路很直接:逐个读取年、月、日、时、分、秒,把个位数前面补上 0,再按顺序拼接起来。
读取本地时间分量的 6 个常用方法如下,它们都自动按当前设备时区返回整数:
getFullYear():返回四位数年份,例如2026。不要使用已废弃的getYear()。getMonth():返回月份索引,范围是0到11,其中0表示 1 月,显示给用户前必须加1。getDate():返回当月第几天,范围是1到31。getHours()、getMinutes()、getSeconds():分别返回 24 小时制的小时(0~23)、分钟(0~59)和秒数(0~59)。
getMonth() 从 0 开始计数,忘记加 1 会让 11 月变成“10 月”;二是不要把 getDate() 和 getDay() 混用——getDate() 才是“几号”,而 getDay() 返回的是星期几(0 代表星期日,1 到 6 代表星期一到星期六)。
单独取出的月、日、时、分、秒在小于 10 时只有一位数字,直接拼接会变成 2026-11-1 9:5:3,秒数跳动时整行文字还会左右晃动。用字符串的 padStart(2, '0') 方法把不足两位的数字前面补零,就能保证每一段始终占两个字符宽度。
function formatLocalTime(date = new Date()) {
const pad = (num) => String(num).padStart(2, '0');
const year = date.getFullYear();
const month = pad(date.getMonth() + 1); // 月份从 0 开始,需要 +1
const day = pad(date.getDate());
const hours = pad(date.getHours());
const minutes = pad(date.getMinutes());
const seconds = pad(date.getSeconds());
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
console.log(formatLocalTime());
2026-11-11 16:05:09
如果界面上还要同时写出星期几,可以利用 getDay() 返回的 0~6 下标,从一个中文数组里直接映射取值,不必写一长串 if/else 判断:
const weekdays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
const now = new Date();
const weekdayText = weekdays[now.getDay()];
console.log(`${formatLocalTime(now)} ${weekdayText}`);
2026-11-11 16:05:09 星期三
用浏览器内置接口输出本地化时间:toLocaleString 与 Intl.DateTimeFormat
如果你的目标不是严格统一的“横杠分隔数字”,而是想直接展示符合中文习惯的日期,比如带有“2026年11月11日 星期三 16:05:09”,或者需要兼容多语言访客,自己写拼接和星期数组就显得繁琐了。这时可以直接使用 JavaScript 内置的本地化格式化能力。
最简短的写法是调用 Date 实例上的 toLocaleString(),传入语言标签 'zh-CN' 和格式选项。把 hour12 设为 false 可以固定使用 24 小时制;如果同时需要只看日期或只看时间,还可以分别使用 toLocaleDateString() 和 toLocaleTimeString()。
const now = new Date();
const text = now.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
weekday: 'long',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
});
console.log(text);
2026/11/11星期三 16:05:09
如果希望输出带上“年月日”字样而不是斜杠,可以把 dateStyle 与 timeStyle 组合起来使用;而当页面需要每秒刷新一次时间时,更推荐使用 Intl.DateTimeFormat 在定时器外部预先创建一个格式化器实例并反复调用 format(date),这样不必每秒重新解析一次区域和配置选项。
const formatter = new Intl.DateTimeFormat('zh-CN', {
dateStyle: 'full',
timeStyle: 'medium',
hour12: false,
});
console.log(formatter.format(new Date()));
2026年11月11日星期三 16:05:09
要注意的是,toLocaleString 和 Intl.DateTimeFormat 的具体分隔符与标点空格会受浏览器内核和系统区域设置影响(例如有的环境返回斜杠 2026/11/11,有的版本空格位置略有不同)。因此,需要严格控制每个符号的格式时优先用上一节的手动分量拼接;面向普通用户做自然语言展示时再选用 Intl.DateTimeFormat。
把时间显示到网页上,并每秒自动刷新
格式化好字符串之后,下一步是让它显示在 HTML 页面上,并且随着时间推移自动走动。最稳妥的做法是在页面放一个带 id 的语义化标签(例如 <time>),在脚本中通过 document.getElementById 找到它,并用 textContent 更新文本。
下面这段完整代码可以直接保存为 index.html 后用任意现代浏览器打开运行:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>当前本地时间</title>
</head>
<body>
<p>当前本地时间:<time id="local-clock">加载中...</time></p>
<script>
const clockEl = document.getElementById('local-clock');
const weekdays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
function formatLocalTime(date) {
const pad = (n) => String(n).padStart(2, '0');
const y = date.getFullYear();
const m = pad(date.getMonth() + 1);
const d = pad(date.getDate());
const hh = pad(date.getHours());
const mm = pad(date.getMinutes());
const ss = pad(date.getSeconds());
const week = weekdays[date.getDay()];
return `${y}-${m}-${d} ${hh}:${mm}:${ss} ${week}`;
}
function renderClock() {
const now = new Date();
clockEl.textContent = formatLocalTime(now);
clockEl.setAttribute('datetime', now.toISOString());
}
// 页面打开时先立即渲染一次,避免首秒空白
renderClock();
// 每 1000 毫秒重新读取一次系统时间并刷新显示
const timerId = setInterval(renderClock, 1000);
// 页面卸载或单页组件销毁时清理定时器
window.addEventListener('beforeunload', () => {
clearInterval(timerId);
});
</script>
</body>
</html>
当前本地时间:2026-11-11 16:13:44 星期三
这段代码里有三处细节值得留意。第一,更新文字使用 textContent 而不是 innerHTML,因为时间文本只是纯字符,textContent 不会触发 HTML 解析,效率更高;第二,在 setInterval(renderClock, 1000) 之前先手动调用了一次 renderClock(),否则用户打开页面的前 1 秒只会看到“加载中...”;第三,如果你把这段逻辑放进 React、Vue 等前端框架组件里,记得在组件卸载钩子中调用 clearInterval(timerId),防止页面切换后定时器继续在后台空转。
实际使用中容易遇到的偏差与排查
即便代码本身没有语法错误,本地时间功能上线后仍可能出现两类看起来像“Bug”的偏差,排查时可以按下面的边界来判断:
1. 网页切到后台再切回来,时钟慢了几秒甚至几分钟
如果有人用“记录初始时间,每次回调给秒数加 1”的方式实现时钟,那么一旦用户把标签页切到后台,或者电脑休眠了几分钟,浏览器为了省电会大幅拉长 setInterval 的执行间隔(甚至降到每分钟一次或暂停)。等用户切回页面时,累加出来的时钟就会明显落后。
解决方法就在上面的示例里:不要自己累加秒数,而是在每次定时器回调里重新执行 new Date()。这样不管后台暂停了多久,只要页面恢复运行,下一次渲染就会立刻对齐设备当前的真实时间。
2. 电脑时间调错了,网页显示也跟着错
JavaScript 运行在用户的浏览器端,new Date() 读取的是用户自己电脑或手机上的系统时钟和时区设置。如果访客的设备系统时间本来就快了 5 分钟,或者时区设错了,网页显示出的“本地时间”也会跟着偏移。对于页脚版权、页面小挂件这类展示用途,这正符合“本地时间”的含义;但如果是倒计时抢购、考试交卷、签名校验等不能被用户修改的场景,就不能只依赖 new Date(),必须由服务端下发标准时间戳,前端只按差值计算经过了多久。
实用工具推荐
绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
选择画质和输出格式,预览压缩前后的大小。