JavaScript Date对象存在时区歧义、构造不一致、方法返回值不统一等问题:字符串解析默认按UTC处理导致本地显示偏差,月份索引从0开始易出错,加减日期应转毫秒计算而非直接修改,格式化推荐toISOString()而非toLocaleDateString()。

JavaScript 的 Date 对象不是“拿来就能算准”的工具,它默认基于本地时区、构造行为不一致、获取/设置方法容易混淆——直接用 new Date().getFullYear() 没问题,但一到跨时区、格式化、加减天数就出错。
为什么 new Date(‘2023-10-01’) 在某些浏览器里变成 9 月 30 日?
因为字符串形式的日期(如 '2023-10-01')被解析为 UTC 时间,再转成本地时区显示。中国用户看到的 new Date('2023-10-01') 实际是 2023-09-30T16:00:00.000Z(UTC 时间),加上东八区偏移后显示为 9 月 30 日下午 4 点。
- 安全写法:用数字参数构造,
new Date(2023, 9, 1)(注意月份是 0 起始) - 若必须用字符串,加时间部分避免歧义:
new Date('2023-10-01T00:00') - Node.js 和 Chrome 较新版本对 ISO 字符串处理更统一,但 Safari 旧版仍可能出错
getMonth() 返回 0–11,但 getHours() 返回 0–23?
这是历史遗留设计:月份从 0 开始是为了和数组索引对齐(方便 ['Jan','Feb',...][date.getMonth()]),而小时/分钟/秒保持自然计数。混用时极易漏掉 +1。
-
date.getDate()→ 当月第几天(1–31)✅ -
date.getMonth()→ 0–11 ❗要 +1 才是“第几月” -
date.getFullYear()→ 推荐替代已废弃的getYear() - 想取“今天是星期几”?用
date.getDay()(0=周日,1=周一…)
如何可靠地加减 7 天、比较两个日期大小?
别用 setDate(date.getDate() + 7) 直接改原对象——它会受月份天数、闰年、夏令时影响,且修改了原始 Date 实例。
立即学习“Java免费学习笔记(深入)”;
- 推荐转为毫秒计算:
new Date(date.getTime() + 7 * 24 * 60 * 60 * 1000) - 比较日期直接用
date1 > date2或date1.getTime() > date2.getTime()(前者隐式调用valueOf()) - 注意:两个
Date对象即使值相同,date1 === date2也是false(引用不同) - 避免用
toDateString()比较,它只含年月日,忽略时分秒
格式化输出时,toLocaleDateString 和 toISOString 哪个更可控?
toISOString() 总返回 UTC 时间的 ISO 8601 字符串(如 '2023-10-01T00:00:00.000Z'),稳定、可预测;toLocaleDateString() 依赖运行环境语言和地区设置,同一段代码在中文系统和英文系统输出不同。
- 需要固定格式(如 API 传参):优先用
toISOString().slice(0, 10)取日期部分 - 面向用户显示:用
toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' })显式指定 locale 和选项 - 不要依赖
toString()或toUTCString(),它们格式不标准、不易解析
真正麻烦的不是记方法名,而是时区转换、夏令时跳变、2 月 29 日边界这些隐性逻辑——哪怕只做「显示今天日期」,也要想清楚:这个“今天”是用户本地的,还是服务器所在时区的,还是 UTC 的。
