JS怎么获取当前月份(1-12)
详细讲解在 JavaScript 中如何正确获取当前自然月份(1-12)。解析 getMonth() 原生返回 0-11 的底层设计原理,演示常规加 1 转换、两位补零(padStart)、国际化展示(Intl.DateTimeFormat)以及跨时区与 setMonth 边界避坑。
在 JavaScript 中,获取当前月份(1-12)最直接的方法是使用 new Date().getMonth() + 1。因为 JavaScript 原生的 Date.prototype.getMonth() 方法返回值范围是 0 到 11(0 代表一月,11 代表十二月),所以在日常业务开发中想要得到大众习惯的 1 到 12 月份,只需要在原返回值的基础上加 1 即可。
假设我们正在开发一个报表筛选组件,需要默认选中“当前月份”,许多初学者直接调用 new Date().getMonth(),却发现明明是十月份,程序却返回了数字 9,进而导致查询了上个月的数据。本文将从最核心的取值写法讲起,解释底层为什么采用 0 索引设计,并系统梳理两位补零、国际化名称获取以及跨时区计算等实用方案与避坑要点。
一、一行代码直接获取当前月份 (1-12)
要获取当前本地时间的自然月份数值,标准的极简写法如下:
// 获取当前月份数值(1 至 12)
const currentMonth = new Date().getMonth() + 1;
console.log(currentMonth);
// 示例输出:如果当前是 10 月,输出数字 10
如果需要同时获取当前的年份、月份和日期,并组合成直观的数值变量,推荐写成复用步骤:
const now = new Date();
const year = now.getFullYear(); // 例如 2026,原生即为实际年份
const month = now.getMonth() + 1; // 范围 1-12,必须 +1
const day = now.getDate(); // 范围 1-31,原生即为实际日期
console.log(`当前时间是:${year}年${month}月${day}日`);
二、为什么 getMonth() 返回的是 0 到 11?
很多开发者会感到疑惑:为什么 getDate() 返回 1 到 31,而 getMonth() 偏偏要返回 0 到 11 呢?这并不是疏忽,而是有明确的技术历史渊源与设计考量:
- 历史规范继承:1995 年 JavaScript 诞生初期,Brendan Eich 在实现
Date对象时参考了早期的 Java 语言设计(java.util.Date),而 Java 又直接沿用了 UNIX 和 C 语言标准库<time.h>中struct tm的定义。在 C 语言结构体中,tm_mon被规定为自一月以来的月数,范围正是0 ~ 11。 - 便于数组下标查表:在没有高级国际化 API 的年代,英语月份通常存放在一个字符串数组中。通过返回
0 ~ 11,开发者可以直接将getMonth()的返回值作为下标提取对应的英文缩写或全称,无需在下标中进行- 1操作:const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; const currentName = monthNames[new Date().getMonth()];
三、常见业务格式化处理与操作流程
在实际项目交互中,单纯拿到数字往往还不能直接满足接口或 UI 规范。根据不同的业务需求,通常分为三种常见处理路径:纯数值、双位补零字符串、以及本地化语言文本。
1. 双位补零格式 ("01" 至 "12")
在构建标准 ISO 日期格式(如 YYYY-MM-DD)或者后端指定的数据键名时,通常要求月份必须是固定的两位字符,例如一月显示为 "01",十月显示为 "10"。
现代 JavaScript(ES2017+)中最优雅的做法是结合 String.prototype.padStart():
const now = new Date();
const monthNumber = now.getMonth() + 1;
// 使用 padStart 进行两位填充(不足两位前置补零)
const formattedMonth = String(monthNumber).padStart(2, '0');
console.log(formattedMonth);
// 示例输出:如果为 5 月,输出 "05";如果为 12 月,输出 "12"
如果需要在较旧的运行环境或小程序旧内核中保持向下兼容,可以使用经典的字符串拼接加截取写法:
const monthStr = ('0' + (now.getMonth() + 1)).slice(-2);
原理是先在数字前面拼一个 '0',变成 '05' 或 '012',再用 slice(-2) 倒数截取最后两位,同样能够稳定获得两位数。
2. 现代国际化原生 API:Intl.DateTimeFormat
如果需要直接获得带有区域语言特征的月份名称(例如中文的“10月”或英文的“October”),无需再手写冗长的映射数组,现代浏览器和 Node.js 原生支持国际化接口 Intl.DateTimeFormat:
const now = new Date();
// 提取双位月份数字
const month2Digit = new Intl.DateTimeFormat('zh-CN', { month: '2-digit' }).format(now);
console.log(month2Digit); // 输出:"10月"
// 提取英文全称
const monthEnFull = new Intl.DateTimeFormat('en-US', { month: 'long' }).format(now);
console.log(monthEnFull); // 输出:"October"
// 提取英文简写
const monthEnShort = new Intl.DateTimeFormat('en-US', { month: 'short' }).format(now);
console.log(monthEnShort); // 输出:"Oct"
四、时区差异:getMonth() 与 getUTCMonth()
在绝大多数前端单机应用中,直接使用 getMonth() 得到的是当前设备操作系统所配置的本地时区时间。但在服务端 Node.js 运行容器、跨境电商或全球协同系统中,务必注意时区引起的月份漂移。
例如,当处于北京时间(东八区,UTC+8)2026 年 5 月 1 日凌晨 04:00 时:
- 使用本地时区方法
now.getMonth() + 1返回的是5。 - 而由于此时全球基准的 UTC 时间是 2026 年 4 月 30 日 20:00,使用
now.getUTCMonth() + 1返回的则是4。
因此在编写跨时区后端日志入库或统计任务时,应明确业务是以“用户当地日历”还是“全局统一 UTC 日历”为统计口径。
五、开发中极易踩坑的 3 个关键细节
1. 隐式类型转换导致字符串拼接
初学者有时会不小心把数字加法写成字符串拼接:
const d = new Date();
// 错误示范:如果手误给 1 加上了引号
const wrongMonth = d.getMonth() + '1';
// 9 + '1' 会变成字符串 "91",而不是数字 10
始终确保 + 1 是纯数值运算,或者显式包裹括号后再转字符串。
2. 使用 setMonth() 变更月份时的跳月溢出
当希望在当前日期的基础上切换月份(例如计算上个月或下个月)时,直接调用 date.setMonth() 存在经典的溢出陷阱。
假设当前时间是 1 月 31 日,如果你调用 date.setMonth(date.getMonth() + 1) 试图得到 2 月,底层实际上会试图生成“2 月 31 日”。由于平年 2 月只有 28 天(闰年 29 天),多出的天数会自动累加进下一个月,导致最终日期直接跳到了 3 月 3 日。
在修改月份前,先将日期重置到该月第一天(1号),再变更月份,避免月末天数不一致造成的自动进位:
const targetDate = new Date();
targetDate.setDate(1); // 先归整为当月 1 号
targetDate.setMonth(targetDate.getMonth() + 1); // 再安全切换月份
3. 注意不要混淆 getDay() 与 getDate()
在 JavaScript 的 Date API 中:
getDate()返回的是当月的几号(1 到 31)。getDay()返回的是星期几(0 代表周日,1-6 代表周一至周六)。getMonth()返回的是月份索引(0 到 11)。
这三个 API 容易让初学者混淆,牢记提取月份只有 getMonth(),提取日期天数是 getDate()。
六、常用方案与特性速查
为了便于日常编码快速查阅,下表整理了获取当前月份的几种核心方案与其适用条件:
| 场景需求 | 代码示例 | 返回值类型 | 典型示例输出 |
|---|---|---|---|
| 基础数值 (1 - 12) | new Date().getMonth() + 1 |
Number |
10 |
| 标准补零 (两位字符) | String(new Date().getMonth() + 1).padStart(2, '0') |
String |
"10" / "05" |
| 格式化年月 (YYYY-MM) | const d=new Date(); `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}` |
String |
"2026-10" |
| 中文本地化 | new Intl.DateTimeFormat('zh-CN', { month: 'long' }).format(new Date()) |
String |
"十月" |
| 英文简写 | new Intl.DateTimeFormat('en-US', { month: 'short' }).format(new Date()) |
String |
"Oct" |
| UTC 基准月份 | new Date().getUTCMonth() + 1 |
Number |
10 |
总结来说,获取当前月份的核心口诀只有一句话:“调用 getMonth() 牢记加一”。在此基础之上,结合 padStart 可以满足所有规范的日期排版格式,而多语言场景则直接交由现代 Intl 原生接口,即可轻松高效地解决所有月份获取与展示需求。
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
p5.js 中 setup() 和 draw() 函数的执行机制详解
2026-11-05 12:32:38
相关标签:








