推荐优先使用 toLocaleDateString() 和 toLocaleTimeString() 组合格式化日期时间,如 'zh-CN' + 显式 options 可稳定输出 "2025-04-01 15:23:45";需毫秒或自定义分隔符时用原生 getter 手动拼接;复杂场景选 date-fns 或 dayjs。
直接 console.log(new Date()) 输出的是类似 "Mon Apr 01 2025 15:23:45 GMT+0800 (中国标准时间)" 的字符串,既难读又含时区信息,不适合展示给用户。浏览器环境里没有内置的通用格式化方法,toLocaleString() 虽然可用,但输出格式受系统语言和区域设置影响,同一段代码在中文 Windows 和英文 macOS 上可能输出 "2025/4/1 下午3:23:45" 或 "4/1/2025, 3:23:45 PM",不可控。
这两个方法支持传入 locales 和 options 参数,能稳定指定年月日、时分秒的显示方式,且兼容性好(IE11+)。关键在于把时间拆成「日期部分」和「时间部分」分别处理,避免混用导致格式错乱。
toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' }) → "2025-04-01"
toLocaleTimeString('zh-CN', { hour12: false
, hour: '2-digit', minute: '2-digit', second: '2-digit' }) → "15:23:45"
"2025-04-01 15:23:45",干净、可控、无歧义en-US 等 locale 强制格式,不同系统仍可能返回 "4/1/2025" 或 "04/01/2025";坚持用 zh-CN + 显式 options 最稳当项目要求固定格式如 "20250401152345678"(无分隔符+毫秒),或想用下划线代替短横线("2025_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}`; // "20250401152345678"
注意:getMonth() 返回 0–11,必须加 1;padStart(2, '0') 比 toString().padStart() 更安全,避免 null 或 undefined 报错。
如果项目中频繁做相对时间(“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)真正难的不是“怎么显示”,而是“要不要支持用户本地时区”“后端返回的时间戳是否带时区”“夏令时切换时会不会跳变”——这些细节一旦忽略,上线后才发现时间差一小时,比格式本身更棘手。