前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
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 热点
旧版
首页程序员面试题库JavaScript new Date 构造器参数 时间基准
JavaScript数据处理

new Date 传数字、传字符串、传多个参数,分别按什么时区算?

传数字,是从 1970-01-01 UTC 零点起的毫秒数;传年、月、日多个参数,按运行环境的本地时区理解,月份从 0 开始;传字符串要看格式,2026-09-10 按 UTC,2026-09-10T00:00 按本地,带 Z 或 +08:00 的才是确定的时间点。

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

输入形式决定按哪个时区理解

  1. 时间戳单个数字就是 UTC 毫秒值,直接存进 Date,不做任何换算
  2. 本地字段年月日时分按本地时区组装,再换算成时间戳
  3. ISO 字符串有 Z 或偏移按它算;只有日期按 UTC;有时间没偏移按本地

2026-09-10 和 2026-09-10T00:00 看起来只差几个字符,在东八区却相差 8 小时。前者是 UTC 零点,后者是本地零点。

核心回答

先记住这个答案

Date 内部只存一个数:距离 1970-01-01T00:00:00Z 的毫秒数。几种构造方式的区别,是怎么算出这个数。传数字,直接就是这个毫秒数。传年、月、日这样的多个参数,按运行环境的本地时区理解,而且月份从 0 开始。传字符串要看格式:带 Z 或 +08:00 就按它说的时区;只有日期的 YYYY-MM-DD 按 UTC;有日期有时间但没写偏移,按本地时区。

  • 数字参数是 UTC 纪元毫秒,和时区无关
  • 多参数按本地时区,月份 0 是一月
  • 只有日期的 ISO 字符串按 UTC,加了时间没偏移按本地
  • 接口传时间点一律带 Z 或偏移

把几种写法放在一起对比

最直观的办法是把它们都转成 toISOString()。toISOString() 永远输出 UTC,看它就知道 Date 里存的到底是哪个时间点。

确定的时间点:数字和带时区的字符串JavaScript
// 数字:从 1970-01-01T00:00:00Z 起的毫秒数
console.log(new Date(0).toISOString())
// 只有日期的 ISO 字符串:按 UTC 零点
console.log(new Date('2026-09-10').toISOString())
// 带 Z:明确是 UTC
console.log(new Date('2026-09-10T08:00:00Z').toISOString())
// 带偏移:东八区 8 点就是 UTC 0 点
console.log(new Date('2026-09-10T08:00:00+08:00').toISOString())
查看输出与解释
1970-01-01T00:00:00.000Z
2026-09-10T00:00:00.000Z
2026-09-10T08:00:00.000Z
2026-09-10T00:00:00.000Z

这四种写法在任何时区的机器上跑,结果都一样,因为输入本身就说清了是哪个时区。第二行容易被忽略:只写日期不写时间,规范规定按 UTC 零点理解,而不是本地零点。

会随机器时区变化的两种写法

另外两种写法没有说明时区,引擎只能用运行环境的本地时区去补。同一行代码放在北京和纽约的机器上,存下的时间戳就不一样。

多参数和不带偏移的日期时间JavaScript
// 以下注释是在东八区(Asia/Shanghai)运行的结果
const a = new Date('2026-09-10') // 只有日期:UTC 零点
const b = new Date('2026-09-10T00:00') // 有时间没偏移:本地零点
const c = new Date(2026, 8, 10) // 多参数:本地零点,8 表示九月

console.log(a.toISOString()) // 2026-09-10T00:00:00.000Z
console.log(b.toISOString()) // 2026-09-09T16:00:00.000Z
console.log(c.toISOString()) // 2026-09-09T16:00:00.000Z
console.log(b.getTime() === c.getTime()) // true

a 和 b 只差一个 T00:00,在东八区却差了 8 小时。这是真实项目里最常见的日期 bug:后端返回 2026-09-10,前端 new Date() 之后用 getDate() 显示,在美洲时区的用户会看到 9 号,因为 UTC 零点在那边还是前一天晚上。 toISOString() 只是把存好的时间戳按 UTC 打印出来,它不会改变构造时的时区选择。差异发生在构造那一步。

月份从 0 开始和日期溢出

多参数构造还有两个老坑。一是月份参数叫 monthIndex,0 是一月,11 是十二月,所以 new Date(2026, 9, 1) 是十月一号。二是字段越界不会报错,会自动进位。

不存在的日期会被悄悄挪走JavaScript
const d = new Date(2026, 1, 31) // 想要 2 月 31 日
console.log(d.getMonth(), d.getDate()) // 月份 2 是三月

const next = new Date(2026, 12, 1) // 月份 12 超出范围
console.log(next.getFullYear(), next.getMonth())
查看输出与解释
2 3
2027 0

2026 年 2 月只有 28 天,31 日多出来的 3 天滚进了三月,得到 3 月 3 日。月份 12 同理,进位成下一年的一月。这个行为有时候很好用,比如 new Date(year, month + 1, 0) 能拿到当月最后一天。但做表单校验时就要当心,构造成功不代表用户输入的日期存在,得把年月日读回来和输入比一下。

回答前,多想一步

容易答错的地方

以为没写 Z 的字符串都按本地时间
只有日期的标准格式 YYYY-MM-DD 是例外,按 UTC 解析。日期加时间但不带偏移,才按本地时间。两种格式长得很像,结果可能差一个时区。
以为 toISOString() 会把本地构造转成 UTC 构造
toISOString() 只是换一种方式显示同一个时间戳。new Date(2026, 8, 10) 在构造时就已经按本地零点算好了,打印出来的 16:00Z 就是本地零点对应的 UTC 时间。
依赖非标准字符串格式
2026/09/10 或者 Sep 10 2026 这类格式大多数浏览器能解析,但规范没有规定,结果可能因实现不同而不同。存储和接口里只用标准的 ISO 8601 格式。
试着用自己的话回答

面试官还会怎么问?

想按 UTC 的年月日构造 Date 怎么写?

用 new Date(Date.UTC(2026, 8, 10))。Date.UTC 接收和多参数构造一样的字段,但按 UTC 理解,返回时间戳。注意它的月份同样从 0 开始。

不传参数的 new Date() 是什么时区?

它就是当前时刻,和时区无关,内部存的是此刻的 UTC 毫秒数。只有在你读 getHours() 或者 toString() 时,才会按本地时区显示出来。

后端传时间,用什么格式最稳?

时间点用带 Z 或明确偏移的 ISO 8601 字符串,或者直接传毫秒时间戳。生日、合同日期这类纯日历日期,传 YYYY-MM-DD 字符串,前端也当字符串处理,别急着 new Date(),否则就会碰上前面说的时区偏一天问题。

从一道题,走向一组知识

把知识连起来

数据处理

夏令时切换那天,用 Date 做时间计算会出什么问题?

多参数构造按本地时间理解,碰上夏令时跳过的那一小时,就会被悄悄挪到别的时间。

数据处理

Date 对象里存的是时间戳还是本地时间?为什么换台电脑打印出来就不一样?

不管用哪种方式构造,Date 最后存下的都只是一个毫秒时间戳,那题讲清楚了存储和显示的分离。

参考资料

  • JavaScript:数据处理参考资料

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

本题目录
  1. 先记住这个答案
  2. 把几种写法放在一起对比
  3. 会随机器时区变化的两种写法
  4. 月份从 0 开始和日期溢出
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

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

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