前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
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 检测 Invalid Date 的方法
JavaScript数据处理

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

用 Number.isNaN(date.getTime())。new Date('abc') 不会返回 null,也不抛错,而是返回一个 Date 对象,只是它内部的时间值是 NaN,所以 instanceof Date 照样是 true。

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

对象是 Date,不代表时间有效

  1. instanceof Date只能说明它是个 Date 对象,Invalid Date 也能通过
  2. getTime()返回内部毫秒数,无效时是 NaN,这才是判断依据
  3. 字段回读用户输入的年月日要构造后读回来比较,防止被自动进位

无效日期用起来很安静,getFullYear() 这类方法只返回 NaN,页面上显示成 NaN 或 Invalid Date。真正抛错的是 toISOString(),而它往往在离出错点很远的序列化环节才被调用。

核心回答

先记住这个答案

new Date() 解析失败时不返回 null,也不抛错,而是返回一个内部时间值为 NaN 的 Date 对象,打印出来是 Invalid Date。它仍然是 Date 实例,所以 instanceof Date 判断不出来。正确的写法是 Number.isNaN(date.getTime()),因为 getTime() 返回内部毫秒数,无效时就是 NaN。另外要注意,new Date(2026, 1, 31) 这种不存在的日期不会变成 Invalid Date,而是被进位成 3 月 3 日,校验用户输入时要单独处理。

  • Invalid Date 也是 Date 实例,时间值是 NaN
  • 检测写法:Number.isNaN(date.getTime())
  • 对无效日期调 toISOString() 会抛 RangeError
  • 2 月 31 日不是无效日期,会被进位成 3 月

Invalid Date 长什么样

先看一个有效日期和一个无效日期在各种检查下的表现。

用内部时间值判断有效性JavaScript
const valid = new Date('2026-09-10T00:00:00Z')
const invalid = new Date('not-a-date')

const isValidDate = (value) =>
  value instanceof Date && !Number.isNaN(value.getTime())

console.log(isValidDate(valid), isValidDate(invalid)) // true false
console.log(invalid instanceof Date, invalid.getTime()) // 仍是 Date,时间值是 NaN
console.log(JSON.stringify({ at: invalid })) // toJSON 返回 null
try {
  invalid.toISOString()
} catch (err) {
  console.log(err.name) // 这里才真正抛错
}
查看输出与解释
true false
true NaN
{"at":null}
RangeError

instanceof 为 true,因为对象确实是用 Date 构造出来的,原型链没问题。坏掉的是它里面存的那个数。所以判断要分两步:先确认是 Date,再确认时间值不是 NaN。 注意 JSON.stringify 那一行。无效日期的 toJSON() 返回 null,不会抛错,结果请求体里悄悄多了一个 null 字段。后端收到时根本分不清是前端没填,还是日期解析坏了。

为什么不用全局 isNaN(date)
isNaN(date) 通常也能得到正确结果,因为它会先把 Date 转成数字,转换时调用的就是 valueOf()。问题在于全局 isNaN 什么都先转数字,传一个普通字符串 'hello' 也返回 true,意图不清楚。Number.isNaN(date.getTime()) 明确说的是「这个 Date 的时间值是不是 NaN」,读代码的人一眼就懂。

2 月 31 日为什么检测不出来

表单里用户选了 2026 年 2 月 31 日,new Date(2026, 1, 31) 构造出来是一个完全有效的日期,只不过是 3 月 3 日。Date 对越界的字段会自动进位,所以 getTime() 不是 NaN,前面的检查拦不住。

构造后把年月日读回来比较JavaScript
function isRealDate(year, month, day) {
  const date = new Date(year, month - 1, day) // 用户输入的月份是 1~12
  return (
    date.getFullYear() === year &&
    date.getMonth() === month - 1 &&
    date.getDate() === day
  )
}

console.log(isRealDate(2026, 2, 28)) // 正常日期
console.log(isRealDate(2026, 2, 31)) // 被进位成 3 月 3 日
console.log(isRealDate(2024, 2, 29)) // 闰年有 29 日
查看输出与解释
true
false
true

思路很简单:日期如果被进位了,读回来的月份或日就会和输入对不上。这个函数同时也挡住了 NaN 输入,因为无效 Date 的 getFullYear() 返回 NaN,和任何数字都不相等。

回答前,多想一步

容易答错的地方

只写 date instanceof Date
Invalid Date 也能通过这个检查。它只能说明对象类型对,说明不了时间值有效,必须再检查 getTime()。
用字符串 'Invalid Date' 做判断
String(date) === 'Invalid Date' 能用,但它依赖的是给人看的展示文本,不是可靠的判断依据。直接检查数值更干净,也不用先转一次字符串。
以为 new Date() 解析失败会抛错
大部分语言的日期解析失败会抛异常,JavaScript 的 Date 不会。它把错误藏在对象里,等到 toISOString() 或者 Intl.DateTimeFormat 格式化时才抛 RangeError。所以要在拿到 Date 的第一时间检查,别等到序列化环节。
试着用自己的话回答

面试官还会怎么问?

Date.parse 能用来检查吗?

能,Date.parse(str) 返回时间戳,解析失败返回 NaN,适合检查字符串。已经有 Date 对象时直接用 getTime() 就行,不用再转回字符串解析一遍。

跨 iframe 传过来的 Date 用 instanceof 会怎样?

每个 iframe 有自己的一套全局对象,父页面的 Date 和子页面的 Date 不是同一个构造函数,instanceof 会返回 false。可以改用 Object.prototype.toString.call(value) === '[object Date]' 判断类型,再检查 getTime()。

两位数的年份会有什么问题?

多参数构造时,0 到 99 的年份会被当成 1900 年加上这个数,new Date(99, 0, 1) 是 1999 年。要构造公元 99 年这种日期,得先建好 Date 再调用 setFullYear(99)。日常业务碰不到,但用户在年份输入框只敲了两位数时就会出现。

从一道题,走向一组知识

把知识连起来

数据处理

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

拿无效日期去调 Intl.DateTimeFormat 的 format() 会抛 RangeError,格式化前先做有效性检查。

数据处理

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

校验日期字符串时常先用正则卡格式,再用 Date 检查值,两题搭配就是一套完整的输入校验。

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

参考资料

  • Date.prototype.getTime()

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

本题目录
  1. 先记住这个答案
  2. Invalid Date 长什么样
  3. 2 月 31 日为什么检测不出来
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

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

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