yearmonth 是处理信用卡有效期的理想类型,支持解析(如“24/12”或“12/2024”)、过期判断(expiry.isbefore(yearmonth.now()))、格式化输出("mm/yy")及与 localdate 协作(如 atendofmonth)。

Java 中用 YearMonth 处理信用卡有效期(如“24/12”表示 2024 年 12 月)非常合适——它专为“年+月”建模,不可变、线程安全、支持比较和格式化,避免了用 String 或 LocalDate 带来的歧义和边界问题。
解析用户输入的年月字符串(如 "24/12" 或 "12/2024")
信用卡有效期常见格式不统一,需先归一化再解析。推荐统一转为“YY/MM”或“MM/YY”,再用 DateTimeFormatter 解析:
- 若输入是
"24/12"(两位年+两位月),用DateTimeFormatter.ofPattern("yy/MM") - 若输入是
"12/2024"(月+四位年),用DateTimeFormatter.ofPattern("MM/yyyy") - 注意:两位年份需明确世纪(如 24 默认为 2024),可用
DateTimeFormatter.withResolverStyle(ResolverStyle.STRICT)配合parseDefaulting(ChronoField.YEAR, 2000)控制基准世纪
示例:
String input = "24/12";
YearMonth expiry = YearMonth.parse(input, DateTimeFormatter.ofPattern("yy/MM"));
// 自动视为 2024 年 12 月
判断是否过期(核心业务逻辑)
信用卡是否有效,本质是:当前年月 ≤ 有效期年月。用 YearMonth.now() 获取当前年月,再调用 isBefore() 或 isAfter():
-
expiry.isBefore(YearMonth.now())→ 已过期(不包含当天) -
!expiry.isBefore(YearMonth.now())或expiry.compareTo(YearMonth.now()) >= 0→ 未过期(含当月) - 注意:无需补日(如设为 1 日),
YearMonth比较天然按“年月”粒度,语义清晰
示例校验方法:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
public static boolean isValid(YearMonth expiry) {
return !expiry.isBefore(YearMonth.now());
}
格式化输出为标准信用卡显示格式(如 "12/24")
前端或打印通常要求 “MM/YY” 格式(如 12/24)。用自定义 DateTimeFormatter 即可:
- 用
DateTimeFormatter.ofPattern("MM/yy")→ 输出 "12/24" - 若需确保年份始终两位(如 2024 → "24"),
yy已自动截取;若需四位年,用yyyy - 避免用
toString()(返回 "2024-12"),不符合金融场景习惯
示例:
YearMonth expiry = YearMonth.of(2024, 12);
String display = expiry.format(DateTimeFormatter.ofPattern("MM/yy")); // "12/24"
安全扩展:与 LocalDate 协作(如计算最后还款日)
有些业务需基于有效期推算具体日期(如“账单日为有效期当月最后一天”)。此时可将 YearMonth 转为 LocalDate:
-
expiry.atDay(1)→ 当月第 1 天(如 2024-12-01) -
expiry.atEndOfMonth()→ 当月最后一天(如 2024-12-31),直接可用 - 避免手动算天数或依赖时区,
atEndOfMonth()内置闰年、大小月逻辑
示例:
LocalDate dueDate = expiry.atEndOfMonth(); // 2024-12-31
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










