前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库Intl.DateTimeFormat 指定时区格式化时间
JavaScript数据处理

页面要同时显示北京时间和纽约时间,用 Intl.DateTimeFormat 怎么写?

创建 Intl.DateTimeFormat 时传 timeZone: 'America/New_York' 这样的 IANA 时区名,format() 出来的就是那个地区的当地时间。Date 本身不变,变的只是显示。locale 管语言和格式,timeZone 管按哪个地区的钟表显示,两者互不影响。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#数据处理
先看核心答案读代码示例
理解线索

一个时间点,按不同地区的钟表显示

  1. Date只存一个 UTC 时间戳,不知道要显示给哪个地区
  2. timeZone决定按哪个地区的规则把时间戳换成年月日时分,包括夏令时
  3. locale决定用中文还是英文、日期先写年还是先写月

zh-CN 只代表中文和中国大陆的格式习惯,不代表北京时间。不传 timeZone 时用的是运行环境的时区,服务器上跑出来可能是 UTC。

核心回答

先记住这个答案

new Intl.DateTimeFormat(locale, { timeZone }) 里的 timeZone 传 IANA 时区名,比如 Asia/Shanghai 和 America/New_York,这样 format(date) 就会按那个地区的规则把时间戳换成当地的年月日时分,夏令时也会自动处理。Date 对象本身不会被修改,服务器也不用切换系统时区。locale 和 timeZone 是两件事:locale 决定显示成中文还是英文、字段怎么排,timeZone 决定显示哪个地区的钟点。

  • timeZone 用 Asia/Shanghai 这种 IANA 名称
  • locale 管语言格式,timeZone 管显示哪个地区的钟点
  • 自定义格式用 formatToParts() 按片段拼
  • 列表里复用同一个 formatter,别每行 new

同一时刻显示成三个地区的时间

做跨境业务或者航班、会议类页面,经常要把同一个时间同时显示成几个地区的当地时间。每个地区建一个 formatter 就行。

显式传 timeZoneJavaScript
const instant = new Date('2026-09-10T00:00:00Z')
const options = {
  year: 'numeric', month: '2-digit', day: '2-digit',
  hour: '2-digit', minute: '2-digit', hourCycle: 'h23'
}

for (const timeZone of ['Asia/Shanghai', 'America/New_York', 'Asia/Tokyo']) {
  const fmt = new Intl.DateTimeFormat('zh-CN', { ...options, timeZone })
  console.log(timeZone, fmt.format(instant))
}
查看输出与解释
Asia/Shanghai 2026/09/10 08:00
America/New_York 2026/09/09 20:00
Asia/Tokyo 2026/09/10 09:00

三行都用中文格式,因为 locale 都是 zh-CN;钟点各不相同,因为 timeZone 不同。纽约这时候用夏令时,是 UTC-4,所以还是 9 号晚上 8 点。如果是 1 月份,formatter 会自动按 UTC-5 算,不用你操心。 hourCycle: 'h23' 让小时按 0~23 显示。不写的话,有些语言默认 12 小时制,会带上午下午。

想要固定格式,用 formatToParts()

format() 的输出格式由语言决定,你没法精确控制。想要 2026-09-10 这种格式,或者要把日期和时间分开渲染,就用 formatToParts() 拿到各个片段自己拼。

按片段拼出 YYYY-MM-DDJavaScript
const fmt = new Intl.DateTimeFormat('en-US', {
  timeZone: 'Asia/Shanghai', year: 'numeric', month: '2-digit', day: '2-digit'
})
const parts = fmt.formatToParts(new Date('2026-09-10T00:00:00Z'))
const get = (type) => parts.find((p) => p.type === type).value
console.log(`${get('year')}-${get('month')}-${get('day')}`)

try {
  new Intl.DateTimeFormat('zh-CN', { timeZone: 'Beijing' }) // 不是合法的 IANA 名称
} catch (err) {
  console.log(err.name)
}
查看输出与解释
2026-09-10
RangeError

formatToParts() 返回的是 { type, value } 数组,type 有 year、month、day、literal 等。按 type 取值,不依赖语言把年放前面还是后面,比用正则去切 format() 的结果稳得多。 时区名写错会在构造时直接抛 RangeError,比如 Beijing 和 GMT+8 都不合法。更坑的是 CST,它不报错,而是被当成美国中部时间 America/Chicago,格式化出来差了十几个小时。中国大陆统一用 Asia/Shanghai。

formatter 要缓存复用
构造 Intl.DateTimeFormat 要解析语言和时区数据,成本不低。一个一千行的订单列表,每行 new 一个 formatter,性能差距很明显。按 locale、timeZone 和选项组合建好实例放在模块顶层或者 useMemo 里,所有行共用。
回答前,多想一步

容易答错的地方

以为传了 zh-CN 就是北京时间
zh-CN 只决定显示成中文、用中国大陆的格式习惯。时区是另一个参数,不传就用运行环境的时区。部署在海外服务器上的 Node 服务,zh-CN 格式化出来可能是 UTC 时间。
用固定偏移代替时区名
Etc/GMT-8 或者较新引擎支持的 +08:00 都能表示东八区,但它们没有夏令时规则。对中国没影响,对纽约、伦敦这类地区,用固定偏移就会有半年差一小时。有夏令时的地区一定要用 America/New_York 这样的地区名。
试着用自己的话回答

面试官还会怎么问?

怎么在时间后面显示「GMT+8」这类时区标记?

加 timeZoneName 选项。short 会显示 GMT+8,纽约夏天显示 GMT-4;换成 long 则显示完整名称,比如「中国标准时间」。具体文本由语言决定,要单独渲染就从 formatToParts() 里取 type 为 timeZoneName 的片段。

怎么知道 formatter 最终用的是哪个时区?

调 fmt.resolvedOptions().timeZone。不传 timeZone 时,它返回运行环境的默认时区,这也是在前端拿用户时区名的常用写法。

Next.js 这类 SSR 页面怎么避免时间显示不一致?

服务端和浏览器的默认时区通常不同,都用默认值格式化,文本就对不上,会触发 hydration 报错。要么把用户时区存进 cookie 或用户设置,服务端格式化时显式传进去;要么时间这一块只在客户端渲染。

从一道题,走向一组知识

把知识连起来

数据处理

new Date 解析失败了怎么判断?instanceof Date 为什么不够?

把 Invalid Date 交给 format() 会直接抛 RangeError,格式化之前先检查时间值是否有效。

数据处理

正则里的前瞻和后顾断言怎么用,有什么区别?

有人会用正则去改 format() 的结果来凑格式,其实 formatToParts() 按片段取值更可靠。

放回知识体系中复习JavaScript 进阶知识

参考资料

  • Intl.DateTimeFormat() constructor

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 同一时刻显示成三个地区的时间
  3. 想要固定格式,用 formatToParts()
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑