112

I get an integer and I need to convert to a month names in various locales:

Example for locale en-us:
1 -> January
2 -> February

Example for locale es-mx:
1 -> Enero
2 -> Febrero

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
atomsfat
  • 2,863
  • 6
  • 34
  • 36
  • 5
    Watch out, Java months are zero-based so 0 = Jan, 1 = Feb, etc – Nick Holt Jun 24 '09 at 14:07
  • you are right, so if a need to change the language, just need to change the locale. Thanks – atomsfat Jun 24 '09 at 14:18
  • 2
    @NickHolt **UPDATE** The modern [`java.timeMonth`](https://docs.oracle.com/javase/9/docs/api/java/time/Month.html) enum is one-based: 1-12 for January-December. Ditto for [`java.time.DayOfWeek](https://docs.oracle.com/javase/9/docs/api/java/time/DayOfWeek.html): 1-7 for Monday-Sunday per ISO 8601 standard. Only the troublesome old legacy date-time classes such as `Calendar` have crazy numbering schemes. One of many reasons to avoid the legacy classes, now supplanted entirely by the *java.time* classes. – Basil Bourque Mar 09 '18 at 17:34

13 Answers13

235
import java.text.DateFormatSymbols;
public String getMonth(int month) {
    return new DateFormatSymbols().getMonths()[month-1];
}
mmcdole
  • 91,488
  • 60
  • 186
  • 222
joe
  • 34,529
  • 29
  • 100
  • 137
  • 12
    Do you not need 'month-1', since the array is zero based ? atomsfat wants 1 -> January etc. – Brian Agnew Jun 24 '09 at 14:04
  • 7
    He does need month-1, because the month is the 1-based month number which needs to be converted to the zero-based array position – Sam Barnum Jun 24 '09 at 14:10
  • This works too, you need to construct DateFormatSymbols with the locale though. – stevedbrown Jun 24 '09 at 14:11
  • 6
    public String getMonth(int month, Locale locale) { return DateFormatSymbols.getInstance(locale).getMonths()[month-1]; } – atomsfat Jun 24 '09 at 14:23
  • 4
    _HE_ needs `month-1`. Anyone else using `Calendar.get(Calendar.MONTH)` will just need `month` – Ron Nov 14 '13 at 11:28
  • 1
    DateFormatSymbols implementation was changed in JDK 8, so getMonths method doesn't return correct values for all Locale's anymore: http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html – ahaaman Apr 10 '14 at 12:30
  • and does anyone know the way to convert from name to int? – John Alexander Betts Aug 13 '18 at 14:21
  • [`DateFormatSymbols`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/text/DateFormatSymbols.html) is part of the terrible date-time classes that are now legacy, as of the adoption of [JSR 310](https://jcp.org/en/jsr/detail?id=310). Now supplanted by the [*java.time*](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html) classes. – Basil Bourque Feb 22 '19 at 23:04
  • I have written this extension for Kotlin developers. fun Int.toMonthName(): String { return DateFormatSymbols().months[this] } – Sadda Hussain Aug 26 '19 at 10:25
46

tl;dr

Month                             // Enum class, predefining and naming a dozen objects, one for each month of the year. 
.of( 12 )                         // Retrieving one of the enum objects by number, 1-12. 
.getDisplayName(
    TextStyle.FULL_STANDALONE , 
    Locale.CANADA_FRENCH          // Locale determines the human language and cultural norms used in localizing. 
)

java.time

Since Java 1.8 (or 1.7 & 1.6 with the ThreeTen-Backport) you can use this:

Month.of(integerMonth).getDisplayName(TextStyle.FULL_STANDALONE, locale);

Note that integerMonth is 1-based, i.e. 1 is for January. Range is always from 1 to 12 for January-December (i.e. Gregorian calendar only).

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Oliv
  • 10,221
  • 3
  • 55
  • 76
  • let's say you have the String Month of May in french using the method you posted (May in french is Mai), how can I get the number 5 from this String?? – usertest Aug 03 '15 at 15:32
  • @usertest I wrote a rough-draft class `MonthDelocalizer` in [my Answer](https://stackoverflow.com/a/39220766/642706) to get a `Month` object from a passed localized month name string: `mai` → Month.MAY. Note that case-sensitivity matters: In French, `Mai` is invalid and should be `mai`. – Basil Bourque Mar 09 '18 at 20:56
  • 1
    It's 2019. How is this not the top answer? – anothernode Sep 19 '19 at 08:04
  • Not work for me. The result is not the name of the month, but the number of the month. You need to use `TextStyle.FULL` to work. – Dherik Mar 05 '21 at 12:39
  • @Dherik I believe this is a JDK bug. `TextStyle.FULL` and `FULL_STANDALONE` are both defined to return "full **text**", see [here](https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/time/format/TextStyle.java#L92-L100). What language do you use? In my language (Slovak) `FULL` gives the month name in genitive, which is good when used in a full date. `FULL_STANDALONE` gives it in nominative, which is good e.g. for choosing in a listbox. – Oliv Mar 08 '21 at 10:40
36

You need to use LLLL for stand-alone month names. this is documented in the SimpleDateFormat documentation, such as:

SimpleDateFormat dateFormat = new SimpleDateFormat( "LLLL", Locale.getDefault() );
dateFormat.format( date );
Anders R. Bystrup
  • 15,729
  • 10
  • 59
  • 55
Ilya Lisway
  • 405
  • 4
  • 5
16

I would use SimpleDateFormat. Someone correct me if there is an easier way to make a monthed calendar though, I do this in code now and I'm not so sure.

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;


public String formatMonth(int month, Locale locale) {
    DateFormat formatter = new SimpleDateFormat("MMMM", locale);
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    calendar.set(Calendar.MONTH, month-1);
    return formatter.format(calendar.getTime());
}
stevedbrown
  • 8,862
  • 8
  • 43
  • 58
14

Here's how I would do it. I'll leave range checking on the int month up to you.

import java.text.DateFormatSymbols;

public String formatMonth(int month, Locale locale) {
    DateFormatSymbols symbols = new DateFormatSymbols(locale);
    String[] monthNames = symbols.getMonths();
    return monthNames[month - 1];
}
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
12

Using SimpleDateFormat.

import java.text.SimpleDateFormat;

public String formatMonth(String month) {
    SimpleDateFormat monthParse = new SimpleDateFormat("MM");
    SimpleDateFormat monthDisplay = new SimpleDateFormat("MMMM");
    return monthDisplay.format(monthParse.parse(month));
}


formatMonth("2"); 

Result: February

sra
  • 23,820
  • 7
  • 55
  • 89
Terence
  • 288
  • 3
  • 3
8

Apparently in Android 2.2 there is a bug with SimpleDateFormat.

In order to use month names you have to define them yourself in your resources:

<string-array name="month_names">
    <item>January</item>
    <item>February</item>
    <item>March</item>
    <item>April</item>
    <item>May</item>
    <item>June</item>
    <item>July</item>
    <item>August</item>
    <item>September</item>
    <item>October</item>
    <item>November</item>
    <item>December</item>
</string-array>

And then use them in your code like this:

/**
 * Get the month name of a Date. e.g. January for the Date 2011-01-01
 * 
 * @param date
 * @return e.g. "January"
 */
public static String getMonthName(Context context, Date date) {

    /*
     * Android 2.2 has a bug in SimpleDateFormat. Can't use "MMMM" for
     * getting the Month name for the given Locale. Thus relying on own
     * values from string resources
     */

    String result = "";

    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    int month = cal.get(Calendar.MONTH);

    try {
        result = context.getResources().getStringArray(R.array.month_names)[month];
    } catch (ArrayIndexOutOfBoundsException e) {
        result = Integer.toString(month);
    }

    return result;
}
galex
  • 3,279
  • 2
  • 34
  • 46
JoachimR
  • 5,150
  • 7
  • 45
  • 50
  • _"Apparently in Android 2.2 there is a bug"_ — It would be useful if you could link to where the bug is tracked. – Peter Hall Apr 03 '17 at 14:44
6

tl;dr

Month.of( yourMonthNumber )           // Represent a month by its number, 1-12 for January-December. 
  .getDisplayName(                    // Generate text of the name of the month automatically localized. 
      TextStyle.SHORT_STANDALONE ,    // Specify how long or abbreviated the name of month should be.
      new Locale( "es" , "MX" )       // Locale determines (a) the human language used in translation, and (b) the cultural norms used in deciding issues of abbreviation, capitalization, punctuation, and so on.
  )                                   // Returns a String.

java.time.Month

Much easier to do now in the java.time classes that supplant these troublesome old legacy date-time classes.

The Month enum defines a dozen objects, one for each month.

The months are numbered 1-12 for January-December.

Month month = Month.of( 2 );  // 2 → February.

Ask the object to generate a String of the name of the month, automatically localized.

Adjust the TextStyle to specify how long or abbreviated you want the name. Note that in some languages (not English) the month name varies if used alone or as part of a complete date. So each text style has a …_STANDALONE variant.

Specify a Locale to determine:

  • Which human language should be used in translation.
  • What cultural norms should decide issues such as abbreviation, punctuation, and capitalization.

Example:

Locale l = new Locale( "es" , "MX" );
String output = Month.FEBRUARY.getDisplayName( TextStyle.SHORT_STANDALONE , l );  // Or Locale.US, Locale.CANADA_FRENCH. 

Name → Month object

FYI, going the other direction (parsing a name-of-month string to get a Month enum object) is not built-in. You could write your own class to do so. Here is my quick attempt at such a class. Use at your own risk. I gave this code no serious thought nor any serious testing.

Usage.

Month m = MonthDelocalizer.of( Locale.CANADA_FRENCH ).parse( "janvier" ) ;  // Month.JANUARY

Code.

package com.basilbourque.example;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.time.Month;
import java.time.format.TextStyle;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

// For a given name of month in some language, determine the matching `java.time.Month` enum object.
// This class is the opposite of `Month.getDisplayName` which generates a localized string for a given `Month` object.
// Usage… MonthDelocalizer.of( Locale.CANADA_FRENCH ).parse( "janvier" ) → Month.JANUARY
// Assumes `FormatStyle.FULL`, for names without abbreviation.
// About `java.time.Month` enum: https://docs.oracle.com/javase/9/docs/api/java/time/Month.html
// USE AT YOUR OWN RISK. Provided without guarantee or warranty. No serious testing or code review was performed.
public class MonthDelocalizer
{
    @NotNull
    private Locale locale;

    @NotNull
    private List < String > monthNames, monthNamesStandalone; // Some languages use an alternate spelling for a “standalone” month name used without the context of a date.

    // Constructor. Private, for static factory method.
    private MonthDelocalizer ( @NotNull Locale locale )
    {
        this.locale = locale;

        // Populate the pair of arrays, each having the translated month names.
        int countMonthsInYear = 12; // Twelve months in the year.
        this.monthNames = new ArrayList <>( countMonthsInYear );
        this.monthNamesStandalone = new ArrayList <>( countMonthsInYear );

        for ( int i = 1 ; i <= countMonthsInYear ; i++ )
        {
            this.monthNames.add( Month.of( i ).getDisplayName( TextStyle.FULL , this.locale ) );
            this.monthNamesStandalone.add( Month.of( i ).getDisplayName( TextStyle.FULL_STANDALONE , this.locale ) );
        }
//        System.out.println( this.monthNames );
//        System.out.println( this.monthNamesStandalone );
    }

    // Constructor. Private, for static factory method.
    // Personally, I think it unwise to default implicitly to a `Locale`. But I included this in case you disagree with me, and to follow the lead of the *java.time* classes. --Basil Bourque
    private MonthDelocalizer ( )
    {
        this( Locale.getDefault() );
    }

    // static factory method, instead of  constructors.
    // See article by Dr. Joshua Bloch. http://www.informit.com/articles/article.aspx?p=1216151
    // The `Locale` argument determines the human language and cultural norms used in de-localizing input strings.
    synchronized static public MonthDelocalizer of ( @NotNull Locale localeArg )
    {
        MonthDelocalizer x = new MonthDelocalizer( localeArg ); // This class could be optimized by caching this object.
        return x;
    }

    // Attempt to translate the name of a month to look-up a matching `Month` enum object.
    // Returns NULL if the passed String value is not found to be a valid name of month for the human language and cultural norms of the `Locale` specified when constructing this parent object, `MonthDelocalizer`.
    @Nullable
    public Month parse ( @NotNull String input )
    {
        int index = this.monthNames.indexOf( input );
        if ( - 1 == index )
        { // If no hit in the contextual names, try the standalone names.
            index = this.monthNamesStandalone.indexOf( input );
        }
        int ordinal = ( index + 1 );
        Month m = ( ordinal > 0 ) ? Month.of( ordinal ) : null;  // If we have a hit, determine the `Month` enum object. Else return null.
        if ( null == m )
        {
            throw new java.lang.IllegalArgumentException( "The passed month name: ‘" + input + "’ is not valid for locale: " + this.locale.toString() );
        }
        return m;
    }

    // `Object` class overrides.

    @Override
    public boolean equals ( Object o )
    {
        if ( this == o ) return true;
        if ( o == null || getClass() != o.getClass() ) return false;

        MonthDelocalizer that = ( MonthDelocalizer ) o;

        return locale.equals( that.locale );
    }

    @Override
    public int hashCode ( )
    {
        return locale.hashCode();
    }

    public static void main ( String[] args )
    {
        // Usage example:
        MonthDelocalizer monthDelocJapan = MonthDelocalizer.of( Locale.JAPAN );
        try
        {
            Month m = monthDelocJapan.parse( "pink elephant" ); // Invalid input.
        } catch ( IllegalArgumentException e )
        {
            // … handle error
            System.out.println( "ERROR: " + e.getLocalizedMessage() );
        }

        // Ignore exception. (not recommended)
        if ( MonthDelocalizer.of( Locale.CANADA_FRENCH ).parse( "janvier" ).equals( Month.JANUARY ) )
        {
            System.out.println( "GOOD - In locale "+Locale.CANADA_FRENCH+", the input ‘janvier’ parses to Month.JANUARY." );
        }
    }
}

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
2

Kotlin Extension

fun Int.toMonthName(): String {
    return DateFormatSymbols().months[this]
}

Usage

calendar.get(Calendar.MONTH).toMonthName()
Sadda Hussain
  • 343
  • 5
  • 19
1

There is an issue when you use DateFormatSymbols class for its getMonthName method to get Month by Name it show Month by Number in some Android devices. I have resolved this issue by doing this way:

In String_array.xml

<string-array name="year_month_name">
    <item>January</item>
    <item>February</item>
    <item>March</item>
    <item>April</item>
    <item>May</item>
    <item>June</item>
    <item>July</item>
    <item>August</item>
    <item>September</item>
    <item>October</item>
    <item>November</item>
    <item>December</item>
    </string-array>

In Java class just call this array like this way:

public String[] getYearMonthName() {
        return getResources().getStringArray(R.array.year_month_names);
        //or like 
       //return cntx.getResources().getStringArray(R.array.month_names);
    } 

      String[] months = getYearMonthName(); 
           if (i < months.length) {
            monthShow.setMonthName(months[i] + " " + year);

            }

Happy Coding :)

Fakhar
  • 3,946
  • 39
  • 35
0
    public static void main(String[] args) {
    SimpleDateFormat format = new SimpleDateFormat("MMMMM", new Locale("en", "US"));
    System.out.println(format.format(new Date()));
}
0

Just inserting the line

DateFormatSymbols.getInstance().getMonths()[view.getMonth()] 

will do the trick.

Kingsley Ijike
  • 1,389
  • 1
  • 8
  • 13
  • 2
    [`DateFormatSymbols`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/text/DateFormatSymbols.html) is part of the terrible date-time classes that are now legacy, as of the adoption of [JSR 310](https://jcp.org/en/jsr/detail?id=310). Now supplanted by the [*java.time*](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html) classes. Suggesting their use in 2019 is poor advice. – Basil Bourque Feb 22 '19 at 23:01
  • This Answer duplicates the content of [the accepted Answer](https://stackoverflow.com/a/1038580/642706). – Basil Bourque Feb 22 '19 at 23:03
0

Try to use this a very simple way and call it like your own func

public static String convertnumtocharmonths(int m){
         String charname=null;
         if(m==1){
             charname="Jan";
         }
         if(m==2){
             charname="Fev";
         }
         if(m==3){
             charname="Mar";
         }
         if(m==4){
             charname="Avr";
         }
         if(m==5){
             charname="Mai";
         }
         if(m==6){
             charname="Jun";
         }
         if(m==7){
             charname="Jul";
         }
         if(m==8){
             charname="Aou";
         }
         if(m==9){
             charname="Sep";
         }
         if(m==10){
             charname="Oct";
         }
         if(m==11){
             charname="Nov";
         }
         if(m==12){
             charname="Dec";
         }
         return charname;
     }
Samer
  • 126
  • 1
  • 9
  • 1
    No need to write this kind of code. Java has built-in [`Month::getDisplayName`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/Month.html#getDisplayName(java.time.format.TextStyle,java.util.Locale)). – Basil Bourque May 17 '19 at 17:35
  • No need to write this boilerplate code. Check my answer posted above. – Sadda Hussain Aug 26 '19 at 10:28