calendar.month 从 0 开始(0 表示 1 月),使用时需读取加 1、设置减 1,并优先迁移到 java.time api;可封装工具方法统一转换,降低出错风险。

Java 中 Calendar.MONTH 从 0 开始(0 表示 1 月,11 表示 12 月),这是历史遗留设计,容易引发越界或错月问题。处理的关键是:**读取时加 1,设置时减 1**,并优先使用更现代的替代方案。
读取月份时记得 +1
从 Calendar 获取月份值后,必须加 1 才能得到人类习惯的 1–12 月:
-
错误写法:
int month = cal.get(Calendar.MONTH); // 得到 0,你以为是 1 月?其实是 1 月没错,但显示成 "0" 就错了 -
正确写法:
int month = cal.get(Calendar.MONTH) + 1; // 得到 1,对应 1 月 - 用于格式化输出、界面展示、日志记录等场景时,这一步不能省
设置月份时记得 -1
向 Calendar 设置月份(比如设为 5 月),传入的值必须是 4(即 5−1):
-
错误写法:
cal.set(Calendar.MONTH, 5); // 实际设成了 6 月 -
正确写法:
cal.set(Calendar.MONTH, 5 - 1); // 或直接 cal.set(Calendar.MONTH, 4) - 如果月份来自用户输入、数据库字段或 API 返回(通常为 1–12),务必先减 1 再 set
优先改用 java.time(推荐)
Calendar 已过时,java.time API(Java 8+)完全规避了这个陷阱:
-
Month枚举:天然支持 1–12(Month.MAY.getValue() == 5) -
LocalDateTime.getMonthValue()直接返回 1–12 -
LocalDateTime.withMonth(5)直接传 5 表示 5 月,无需换算 - 示例:
LocalDate.now().getMonthValue()→ 稳定返回 1–12
封装工具方法降低出错概率
如果仍需兼容旧代码,可封装统一转换逻辑,减少散落各处的 +1/−1:
- 定义静态工具方法:
static int toMonthIndex(int humanMonth) { return humanMonth - 1; } - 和
static int toHumanMonth(int calendarMonth) { return calendarMonth + 1; } - 所有 Calendar 的 get/set 操作都走这些方法,避免手误
- 配合 IDE 提醒或单元测试覆盖边界值(如 0、12、13)效果更好
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











