1. Overview

When working with months in Java, we often leverage the numerical format because it helps standardize across different languages and regions as month names vary widely.

In this short tutorial, we’ll learn different ways of converting a month’s name to its respective number. First, we’ll see how to do this using JDK. Then, we’ll discuss how to achieve the same outcome using the third-party Joda-Time library.

2. Using the Java 8+ Date-Time API

Java 8 is frequently praised for its introduction of the new Date-Time API, designed to address the shortcomings of the legacy date API. So, let’s see how to use this new API to answer our central question.

2.1. Using Month

The easiest solution would be using the Month enum. As the name implies, it models the 12 months of the year. In addition to the textual names, each constant has an int value from 1 (January) to 12 (December).

So, let’s see it in action:

@Test
void givenMonthName_whenUsingMonthEnum_thenReturnNumber() {
    String givenMonthName = "October";
    int expectedMonthNumber = 10;

    int monthNumber = Month.valueOf(givenMonthName.toUpperCase())
      .getValue();

    assertEquals(expectedMonthNumber, monthNumber);
}

As we see above, we use the valueOf() method to get the int value of the passed month name. Since it’s an enum, we use the toUpperCase() method to convert the input to uppercase before calling valueOf().

2.2. Using ChronoField

ChronoField is another enum that we can use to get the number of a given month. It denotes a standard set of fields that provide access to temporal information such as days, months, and years.

So, let’s see it in practice:

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

}

As we can see, we used the MMM format which is a short form of the month using three characters. Then, we passed the MONTH_OF_YEAR  constant to the get() method. That way we get the number of the given month “Sep”.

3. Using the Legacy Date API

Before Java 8, we typically used Date or Calendar to manipulate or work with temporal objects. So, let’s go down the rabbit hole and see how to use these legacy classes to convert a month’s name to its corresponding number:

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

Here, we use SimpleDateFormat with the pattern MMM to parse the abbreviated month name into a Date object. Furthermore, we create an instance of Calendar and set the Date object, which represents the parsed month, as the time for the calendar.

Lastly, we retrieve the month from the calendar using the get() method. Typically, Calendar.MONTH is zero-based (January is 0, February is 1, etc.),  so we add 1 to get the correct month number.

4. Using Joda-Time

Joda-Time is another option to consider to tackle our challenge. First, let’s add its dependency to the pom.xml file:

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.12.7</version>
</dependency>

Similarly, Joda-Time offers a convenient method called getMonthOfYear() that we can use to get the number of a given month:

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

As illustrated, the logic remains the same as previously seen. Here, we use the getMonthOfYear() to get the numerical value of the parsed month name.

5. Conclusion

In this short article, we explored different ways of converting a month’s name into its respective number.

First, we saw how to do the conversion using JDK. Then, we learned how to achieve the same result using the Joda-Time library.

As always, the code used in this article can be found over on GitHub.