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之前,我们通常用DateCalendar处理时间。下面看看如何用这些老古董实现转换:

@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);
}

流程:

  1. SimpleDateFormat解析月份缩写("May")
  2. 创建Calendar实例并设置时间
  3. 获取月份值(⚠️ 注意: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仓库


原始标题:Getting Month Number From Its Name in Java | Baeldung