作为字符串的月份名称

我试图以字符串的形式返回月份的名称,例如“ May”、“ September”、“ November”。

我试过:

int month = c.get(Calendar.MONTH);

但是,这将返回整数(分别为5、9、11)。如何获得月份名称?

152905 次浏览

Use getDisplayName.

For earlier API's use String.format(Locale.US,"%tB",c);

I keep this answer which is useful for other cases, but @trutheality answer seems to be the most simple and direct way.

You can use DateFormatSymbols

DateFormatSymbols(Locale.FRENCH).getMonths()[month]; // FRENCH as an example

Use this :

Calendar cal=Calendar.getInstance();
SimpleDateFormat month_date = new SimpleDateFormat("MMMM");
String month_name = month_date.format(cal.getTime());

Month name will contain the full month name,,if you want short month name use this

 SimpleDateFormat month_date = new SimpleDateFormat("MMM");
String month_name = month_date.format(cal.getTime());

For getting month in string variable use the code below

For example the month of September:

M -> 9

MM -> 09

MMM -> Sep

MMMM -> September

String monthname=(String)android.text.format.DateFormat.format("MMMM", new Date())

As simple as this

mCalendar = Calendar.getInstance();
String month = mCalendar.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault());

Calendar.LONG is to get the full name of the month and Calendar.SHORT gives the name in short. For eg: Calendar.LONG will return January Calendar.SHORT will return Jan

"MMMM" is definitely NOT the right solution (even if it works for many languages), use "LLLL" pattern with SimpleDateFormat

The support for 'L' as ICU-compatible extension for stand-alone month names was added to Android platform on Jun. 2010.

Even if in English there is no difference between the encoding by 'MMMM' and 'LLLL', your should think about other languages, too.

E.g. this is what you get, if you use Calendar.getDisplayName or the "MMMM" pattern for January with the Russian Locale:

января (which is correct for a complete date string: "10 января, 2014")

but in case of a stand-alone month name you would expect:

январь

The right solution is:

 SimpleDateFormat dateFormat = new SimpleDateFormat( "LLLL", Locale.getDefault() );
dateFormat.format( date );

If you are interested in where all the translations come from - here is the reference to gregorian calendar translations (other calendars linked on top of the page).

Getting a standalone month name is surprisingly difficult to perform "right" in Java. (At least as of this writing. I'm currently using Java 8).

The problem is that in some languages, including Russian and Czech, the standalone version of the month name is different from the "formatting" version. Also, it appears that no single Java API will just give you the "best" string. The majority of answers posted here so far only offer the formatting version. Pasted below is a working solution for getting the standalone version of a single month name, or getting an array with all of them.

I hope this saves someone else some time!

/**
* getStandaloneMonthName, This returns a standalone month name for the specified month, in the
* specified locale. In some languages, including Russian and Czech, the standalone version of
* the month name is different from the version of the month name you would use as part of a
* full date. (Different from the formatting version).
*
* This tries to get the standalone version first. If no mapping is found for a standalone
* version (Presumably because the supplied language has no standalone version), then this will
* return the formatting version of the month name.
*/
private static String getStandaloneMonthName(Month month, Locale locale, boolean capitalize) {
// Attempt to get the standalone version of the month name.
String monthName = month.getDisplayName(TextStyle.FULL_STANDALONE, locale);
String monthNumber = "" + month.getValue();
// If no mapping was found, then get the formatting version of the month name.
if (monthName.equals(monthNumber)) {
DateFormatSymbols dateSymbols = DateFormatSymbols.getInstance(locale);
monthName = dateSymbols.getMonths()[month.getValue()];
}
// If needed, capitalize the month name.
if ((capitalize) && (monthName != null) && (monthName.length() > 0)) {
monthName = monthName.substring(0, 1).toUpperCase(locale) + monthName.substring(1);
}
return monthName;
}


/**
* getStandaloneMonthNames, This returns an array with the standalone version of the full month
* names.
*/
private static String[] getStandaloneMonthNames(Locale locale, boolean capitalize) {
Month[] monthEnums = Month.values();
ArrayList<String> monthNamesArrayList = new ArrayList<>();
for (Month monthEnum : monthEnums) {
monthNamesArrayList.add(getStandaloneMonthName(monthEnum, locale, capitalize));
}
// Convert the arraylist to a string array, and return the array.
String[] monthNames = monthNamesArrayList.toArray(new String[]{});
return monthNames;
}

The only one way on Android to get properly formatted stanalone month name for such languages as ukrainian, russian, czech

private String getMonthName(Calendar calendar, boolean short) {
int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY | DateUtils.FORMAT_NO_YEAR;
if (short) {
flags |= DateUtils.FORMAT_ABBREV_MONTH;
}
return DateUtils.formatDateTime(getContext(), calendar.getTimeInMillis(), flags);
}

Tested on API 15-25

Output for May is Май but not Мая

I would recommend to use Calendar object and Locale, because month names are different for different languages:

// index can be in range 0 - 11
private String getMonthName(final int index, final Locale locale, final boolean shortName)
{
String format = "%tB";


if (shortName)
format = "%tb";


Calendar calendar = Calendar.getInstance(locale);
calendar.set(Calendar.MONTH, index);
calendar.set(Calendar.DAY_OF_MONTH, 1);


return String.format(locale, format, calendar);
}

Example for full month name:

System.out.println(getMonthName(0, Locale.US, false));

Result: January

Example for short month name:

System.out.println(getMonthName(0, Locale.US, true));

Result: Jan

A sample way to get the date and time in this format "2018 Nov 01 16:18:22" use this

DateFormat dateFormat = new SimpleDateFormat("yyyy MMM dd HH:mm:ss");
Date date = new Date();
dateFormat.format(date);

Russian.

Month
.MAY
.getDisplayName(
TextStyle.FULL_STANDALONE ,
new Locale( "ru" , "RU" )
)

май

English in the United States.

Month
.MAY
.getDisplayName(
TextStyle.FULL_STANDALONE ,
Locale.US
)

May

See this code run live at IdeOne.com.

ThreeTenABP and java.time

Here’s the modern answer. When this question was asked in 2011, Calendar and GregorianCalendar were commonly used for dates and times even though they were always poorly designed. That’s 8 years ago now, and those classes are long outdated. Assuming you are not yet on API level 26, my suggestion is to use the ThreeTenABP library, which contains an Android adapted backport of java.time, the modern Java date and time API. java.time is so much nicer to work with.

Depending on your exact needs and situation there are two options:

  1. Use Month and its getDisplayName method.
  2. Use a DateTimeFormatter.

Use Month

    Locale desiredLanguage = Locale.ENGLISH;
Month m = Month.MAY;
String monthName = m.getDisplayName(TextStyle.FULL, desiredLanguage);
System.out.println(monthName);

Output from this snippet is:

May

In a few languages it will make a difference whether you use TextStyle.FULL or TextStyle.FULL_STANDALONE. You will have to see, maybe check with your users, which of the two fits into your context.

Use a DateTimeFormatter

If you’ve got a date with or without time of day, I find a DateTimeFormatter more practical. For example:

    DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MMMM", desiredLanguage);


ZonedDateTime dateTime = ZonedDateTime.of(2019, 5, 31, 23, 49, 51, 0, ZoneId.of("America/Araguaina"));
String monthName = dateTime.format(monthFormatter);

I am showing the use of a ZonedDateTime, the closest replacement for the old Calendar class. The above code will work for a LocalDate, a LocalDateTime, MonthDay, OffsetDateTime and a YearMonth too.

What if you got a Calendar from a legacy API not yet upgraded to java.time? Convert to a ZonedDateTime and proceed as above:

    Calendar c = getCalendarFromLegacyApi();
ZonedDateTime dateTime = DateTimeUtils.toZonedDateTime(c);

The rest is the same as before.

Question: Doesn’t java.time require Android API level 26?

java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

It will provide current date and month:

 fun getDateTime(): String?
{
val dateFormat: DateFormat = SimpleDateFormat("dd MMMM")
val date = Date()
return dateFormat.format(date)
}