推荐优先使用 toLocaleDateString() 和 toLocaleTimeString() 组合格式化日期时间,如 'zh-CN' + 显式 options 可稳定输出 "2024-04-01 15:23:45";需毫秒或自定义分隔符时用原生 getter 手动拼接;复杂场景选 date-fns 或 dayjs。

new Date() 生成的日期对象默认 toString() 太长又不统一
直接 console.log(new Date()) 输出的是类似 "Mon Apr 01 2024 15:23:45 GMT+0800 (中国标准时间)" 的字符串,既难读又含时区信息,不适合展示给用户。浏览器环境里没有内置的通用格式化方法,toLocaleString() 虽然可用,但输出格式受系统语言和区域设置影响,同一段代码在中文 Windows 和英文 macOS 上可能输出 "2024/4/1 下午3:23:45" 或 "4/1/2024, 3:23:45 PM",不可控。
Date.prototype.toLocaleDateString() 和 toLocaleTimeString() 可以按需拆分控制
这两个方法支持传入 locales 和 options 参数,能稳定指定年月日、时分秒的显示方式,且兼容性好(IE11+)。关键在于把时间拆成「日期部分」和「时间部分」分别处理,避免混用导致格式错乱。
-
toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' })→"2024-04-01" -
toLocaleTimeString('zh-CN', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' })→"15:23:45" - 拼起来就是
"2024-04-01 15:23:45",干净、可控、无歧义 - 注意:不要用
en-US等 locale 强制格式,不同系统仍可能返回"4/1/2024"或"04/01/2024";坚持用zh-CN+ 显式options最稳
需要精确到毫秒或自定义分隔符?手动拼接 getFullYear() 等方法更可靠
当项目要求固定格式如 "20240401152345678"(无分隔符+毫秒),或想用下划线代替短横线("2024_04_01"),toLocale* 就不够用了。此时应调用原生 getter 方法,自己补零、拼接。
const d = new Date();
const y = d.getFullYear();
const m = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
const h = String(d.getHours()).padStart(2, '0');
const min = String(d.getMinutes()).padStart(2, '0');
const s = String(d.getSeconds()).padStart(2, '0');
const ms = String(d.getMilliseconds()).padStart(3, '0');
const formatted = `${y}${m}${day}${h}${min}${s}${ms}`; // "20240401152345678"
注意:getMonth() 返回 0–11,必须加 1;padStart(2, '0') 比 toString().padStart() 更安全,避免 null 或 undefined 报错。
立即学习“Java免费学习笔记(深入)”;
第三方库如 date-fns 或 dayjs 是复杂场景的省心选择
如果项目中频繁做相对时间(“2小时前”)、时区转换、周计算(“本周一”)、或需支持大量 locale 格式,硬写原生逻辑容易出错且维护成本高。这时候引入轻量库更实际:
-
date-fns是函数式、tree-shakable 的,format(new Date(), 'yyyy-MM-dd HH:mm:ss')直观且不污染原型链 -
dayjs体积小、API 类似 Moment.js 但不可变,dayjs().format('YYYY-MM-DD HH:mm:ss')写法熟悉 - 注意:不要只为简单格式化引入整包
moment,它已进入维护模式,且体积大(>200KB)
真正难的不是“怎么显示”,而是“要不要支持用户本地时区”“后端返回的时间戳是否带时区”“夏令时切换时会不会跳变”——这些细节一旦忽略,上线后才发现时间差一小时,比格式本身更棘手。











