1. 概述
在Java中处理月份时,我们经常使用数字格式,因为不同语言和地区的月份名称差异很大,数字格式能更好地标准化。
这篇短文将介绍几种将月份名称转换为对应数字的方法。首先我们使用JDK原生实现,然后探讨如何用第三方库Joda-Time达到相同效果。
2. 使用Java 8+日期时间API
Java 8引入的新日期时间API解决了旧版API的诸多缺陷,下面看看如何用它解决我们的问题。
2.1. 使用Month枚举
最简单粗暴的方案是直接用Month
枚举。它直接建模了1-12月,每个常量除了文本名称外,还包含1(一月)到12(十二月)的整数值。
看代码:
@Test
void givenMonthName_whenUsingMonthEnum_thenReturnNumber() {
String givenMonthName = "October";
int expectedMonthNumber = 10;
int monthNumber = Month.valueOf(givenMonthName.toUpperCase())
.getValue();
assertEquals(expectedMonthNumber, monthNumber);
}
这里先用toUpperCase()
将输入转为大写(因为枚举值是大写的),再用valueOf()
获取枚举实例,最后用getValue()
取数字值。⚠️ 注意输入必须严格匹配枚举名称(如"OCTOBER")。
2.2. 使用ChronoField枚举
ChronoField
是另一个可用枚举,它定义了一套标准字段用于访问时间信息(如日、月、年)。
实操如下:
@Test
void givenMonthName_whenUsingChronoFieldEnum_thenReturnNumber() {
String givenMonthName = "Sep";
int expectedMonthNumber = 9;
int monthNumber = DateTimeFormatter.ofPattern("MMM")
.withLocale(Locale.ENGLISH)
.parse(givenMonthName)
.get(ChronoField.MONTH_OF_YEAR);
assertEquals(expectedMonthNumber, monthNumber);
}
这里用MMM
格式解析三字母缩写月份(如"Sep"),然后通过MONTH_OF_YEAR
字段获取月份数字。✅ 支持多语言(需设置Locale)。
3. 使用旧版日期API
Java 8之前,我们通常用Date
或Calendar
处理时间。下面看看如何用这些老古董实现转换:
@Test
void givenMonthName_whenUsingDateLegacyAPI_thenReturnNumber() throws ParseException {
String givenMonthName = "May";
int expectedMonthNumber = 5;
Date date = new SimpleDateFormat("MMM", Locale.ENGLISH).parse(givenMonthName);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int monthNumber = calendar.get(Calendar.MONTH) + 1;
assertEquals(expectedMonthNumber, monthNumber);
}
流程:
- 用
SimpleDateFormat
解析月份缩写("May") - 创建
Calendar
实例并设置时间 - 获取月份值(⚠️ 注意:
Calendar.MONTH
从0开始,所以必须+1)
4. 使用Joda-Time库
Joda-Time是另一个强力选项。先在pom.xml
添加依赖:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.12.7</version>
</dependency>
它提供了便捷的getMonthOfYear()
方法直接获取月份数字:
@Test
void givenMonthName_whenUsingJodaTime_thenReturnNumber() {
String givenMonthName = "April";
int expectedMonthNumber = 4;
int monthNumber = DateTimeFormat.forPattern("MMM")
.withLocale(Locale.ENGLISH)
.parseDateTime(givenMonthName)
.getMonthOfYear();
assertEquals(expectedMonthNumber, monthNumber);
}
逻辑和Java 8的ChronoField
方案类似,但API更简洁直观。✅ 特别适合旧项目迁移。
5. 总结
这篇短文探讨了四种将月份名称转换为数字的方法:
- Java 8+:
Month
枚举(最简单)或ChronoField
(更灵活) - 旧版API:
Calendar
(需注意0基准) - Joda-Time:
getMonthOfYear()
(推荐用于旧项目)
每种方案各有适用场景,按需选择即可。完整代码见GitHub仓库。