——从 toUTCString() 到 Intl.DateTimeFormat 的深度理解
时间与日期,是前端开发中最容易“踩坑”的部分。不同浏览器、不同区域、甚至不同系统语言,都会造成输出不一致。
本文将系统解析 JavaScript 提供的时间格式化方法,帮你彻底搞懂它们的差异、用途与正确使用方式。
一、背景:为什么会有这么多时间格式化方法?
JavaScript 的时间系统基于 ECMAScript 时间标准,时间点以 UTC 为基准(Unix Epoch:1970-01-01 00:00:00 UTC)。
但由于前端代码运行在不同地域的用户设备中,所以:
- 一部分方法输出国际标准格式(机器可读);
- 一部分方法输出本地化格式(用户可读);
- 一部分方法支持自定义区域、时区和格式。
二、核心 API 总览表
| 方法 | 时区 | 是否本地化 | 是否可定制 | 输出示例 | 主要用途 |
|---|---|---|---|---|---|
| toString() | 本地时间 | 否 | 否 | "Tue Nov 11 2025 17:00:00 GMT+0800 (China Standard Time)" | 调试/默认输出 |
| toUTCString() | UTC | 否 | 否 | "Tue, 11 Nov 2025 09:00:00 GMT" | 标准化输出(日志/HTTP) |
| toGMTString() | UTC | 否 | 否 | "Tue, 11 Nov 2025 09:00:00 GMT" | 历史遗留(不推荐) |
| toISOString() | UTC | 否 | 否 | "2025-11-11T09:00:00.000Z" | 数据交换(JSON/HTTP) |
| toLocaleString() | 本地时区 | ✅ 是 | ✅ 是 | "2025/11/11 17:00:00" | 用户界面显示 |
| Intl.DateTimeFormat | 任意指定 | ✅ 是 | ✅ 是 | "11 November 2025, 17:00:00" | 完全可控本地化输出 |
三、逐个详解与代码示例
① toUTCString()
用途:输出 UTC 时间的 RFC1123 标准格式
语法:
1date.toUTCString(); 2
示例:
1const d = new Date('2025-11-11T09:00:00Z'); 2console.log(d.toUTCString()); 3// "Tue, 11 Nov 2025 09:00:00 GMT" 4
特性:
- 输出固定格式,不可配置;
- 常用于日志、HTTP Header;
- 不受系统区域影响。
适用场景:
1// 设置 HTTP 响应头 2response.setHeader('Expires', new Date(Date.now() + 3600000).toUTCString()); 3
② toGMTString()(已废弃)
用途:toUTCString() 的旧版本,早期 Netscape/IE 兼容接口。
语法:
1date.toGMTString(); 2
说明:
- 在现代浏览器中行为与
toUTCString()相同; - ECMAScript 已标记为 deprecated;
- 不推荐使用,仅兼容老项目。
③ [toLocaleString()](function toLocaleString() { [native code] })
用途:输出与用户地区语言相符的本地化时间字符串。
语法:
1date.toLocaleString([locales], [options]); 2
参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
| locales | string 或 string[] | 语言代码(如 'zh-CN', 'en-US') |
| options | object | 格式化选项 |
常用选项:
1{ 2 timeZone: 'Asia/Shanghai', // 指定时区 3 year: 'numeric', 4 month: '2-digit', 5 day: '2-digit', 6 hour: '2-digit', 7 minute: '2-digit', 8 second: '2-digit', 9 hour12: false 10} 11
示例:
1const d = new Date('2025-11-11T09:00:00Z'); 2console.log(d.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })); 3// "2025/11/11 17:00:00" 4 5console.log(d.toLocaleString('en-US', { timeZone: 'America/New_York' })); 6// "11/11/2025, 4:00:00 AM" 7
✅ 可本地化、可控、最灵活。
④ toISOString()
用途:输出 ISO 8601 标准的 UTC 时间字符串。
语法:
1date.toISOString(); 2
输出示例:
1new Date('2025-11-11T09:00:00Z').toISOString(); 2// "2025-11-11T09:00:00.000Z" 3
特性:
- 输出固定格式;
- 精确到毫秒;
- 常用于 JSON / 数据交换;
- Node.js 和后端系统高度兼容。
示例:
1JSON.stringify({ createdAt: new Date().toISOString() }); 2
⑤ Intl.DateTimeFormat
用途:提供强大的国际化时间格式化能力。
语法:
1new Intl.DateTimeFormat(locales, options).format(date); 2
示例:
1const d = new Date('2025-11-11T09:00:00Z'); 2const fmt = new Intl.DateTimeFormat('en-GB', { 3 timeZone: 'UTC', 4 dateStyle: 'full', 5 timeStyle: 'long' 6}); 7console.log(fmt.format(d)); 8// "Tuesday, 11 November 2025 at 09:00:00 GMT" 9
更细粒度控制:
1const custom = new Intl.DateTimeFormat('zh-CN', { 2 timeZone: 'Asia/Shanghai', 3 year: 'numeric', 4 month: 'long', 5 day: 'numeric', 6 weekday: 'long', 7 hour: '2-digit', 8 minute: '2-digit' 9}); 10console.log(custom.format(d)); 11// "2025年11月11日星期二 17:00" 12
✅ 支持:
- 时区切换;
- 多语言;
- 长短日期格式;
- 星期显示;
- 本地化数字。
四、对比实测:同一个时间,不同输出
1const d = new Date('2025-11-11T09:00:00Z'); 2 3console.log(d.toString()); // "Tue Nov 11 2025 17:00:00 GMT+0800 (China Standard Time)" 4console.log(d.toUTCString()); // "Tue, 11 Nov 2025 09:00:00 GMT" 5console.log(d.toISOString()); // "2025-11-11T09:00:00.000Z" 6console.log(d.toLocaleString()); // "2025/11/11 17:00:00" 7console.log( 8 new Intl.DateTimeFormat('en-US', { timeZone: 'UTC' }).format(d) 9); // "11/11/2025" 10
📊 总结图示:
| 方法 | 时区 | 输出可定制 | 推荐用途 |
|---|---|---|---|
| toUTCString() | UTC | ❌ | 机器可读、HTTP Header |
| toGMTString() | UTC | ❌ | 已废弃 |
| toLocaleString() | 本地时区 | ✅ | 用户界面展示 |
| toISOString() | UTC | ❌ | 数据序列化、存储 |
| Intl.DateTimeFormat | 任意 | ✅✅✅ | 最强国际化控制 |
五、潜在问题与实战建议
| 问题 | 说明 | 建议 |
|---|---|---|
| 不同浏览器格式差异 | 特别是 toLocaleString() | 显式指定 locale + timeZone |
| 服务器和客户端时区不一致 | SSR 输出 UTC、CSR 输出本地 | 统一 timeZone(如 'UTC' 或 'Asia/Shanghai') |
| 想统一格式输出 | toUTCString() 太固定 | 改用 Intl.DateTimeFormat 或 dayjs |
| 移动端差异 | ICU 版本不同 | 避免依赖系统默认格式 |
六、实践案例:统一格式化函数封装
1function formatDate(date, opts = {}) { 2 const { 3 locale = 'zh-CN', 4 timeZone = 'Asia/Shanghai', 5 options = {} 6 } = opts; 7 8 const fmt = new Intl.DateTimeFormat(locale, { 9 timeZone, 10 year: 'numeric', 11 month: '2-digit', 12 day: '2-digit', 13 hour: '2-digit', 14 minute: '2-digit', 15 second: '2-digit', 16 hour12: false, 17 ...options 18 }); 19 return fmt.format(date); 20} 21 22console.log(formatDate(new Date(), { timeZone: 'UTC' })); 23// 输出如:2025/11/11 09:00:00 24
七、结语:选择建议总结
| 场景 | 推荐 API |
|---|---|
| 机器通信 / JSON / HTTP | toISOString() / toUTCString() |
| 用户界面显示(国际化) | toLocaleString() 或 Intl.DateTimeFormat |
| 跨区域一致性(前后端) | 固定使用 UTC + 格式化控制 |
| 需要灵活格式 | 使用 Intl.DateTimeFormat 或 dayjs |
一句话总结:
toUTCString():标准化 UTC 文本输出- [
toLocaleString()](function toLocaleString() { [native code] }):本地化用户界面输出toISOString():数据传输标准输出Intl.DateTimeFormat:国际化与自定义格式首选
本文部分内容借助 AI 辅助生成,并由作者整理审核。
《📘 全面解析:JavaScript 时间格式化 API 实战指南》 是转载文章,点击查看原文。