Как я могу преобразовать Integer в локализованное название месяца в Java? - PullRequest
91 голосов
/ 24 июня 2009

Я получаю целое число, и мне нужно преобразовать названия месяцев в различные локали:

Пример локали en-us:
1 -> января
2 -> февраля

Пример локали es-mx:
1 -> Энерго
2 -> Фебреро

Ответы [ 12 ]

197 голосов
/ 24 июня 2009
import java.text.DateFormatSymbols;
public String getMonth(int month) {
    return new DateFormatSymbols().getMonths()[month-1];
}
32 голосов
/ 30 января 2013

Вам нужно использовать LLLL для автономных названий месяцев. это задокументировано в документации SimpleDateFormat, например:

SimpleDateFormat dateFormat = new SimpleDateFormat( "LLLL", Locale.getDefault() );
dateFormat.format( date );
16 голосов
/ 24 июня 2009

Я бы использовал SimpleDateFormat. Кто-то поправит меня, если есть более простой способ сделать календарь монтированным, я делаю это сейчас в коде и не уверен в этом.

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());
}
13 голосов
/ 13 января 2015

java.time

Начиная с Java 1.8 (или 1.7 и 1.6 с ThreeTen-Backport ), вы можете использовать это:

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

Обратите внимание, что integerMonth основано на 1, т.е. 1 на январь. Диапазон всегда от 1 до 12 для января-декабря (т.е. только по григорианскому календарю).

13 голосов
/ 24 июня 2009

Вот как бы я это сделал. Я оставлю проверку диапазона на int month на ваше усмотрение.

import java.text.DateFormatSymbols;

public String formatMonth(int month, Locale locale) {
    DateFormatSymbols symbols = new DateFormatSymbols(locale);
    String[] monthNames = symbols.getMonths();
    return monthNames[month - 1];
}
10 голосов
/ 28 сентября 2011

Использование 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"); 

Результат: февраль

7 голосов
/ 09 октября 2011

Видимо в Android 2.2 есть ошибка с SimpleDateFormat.

Чтобы использовать названия месяцев, вы должны сами определить их в своих ресурсах:

<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>

А затем используйте их в своем коде так:

/**
 * 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;
}
6 голосов
/ 30 августа 2016

ТЛ; др

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

Гораздо проще сделать это сейчас в классах java.time, которые вытесняют эти утомительные старые унаследованные классы даты и времени.

Перечисление Month определяет дюжину объектов, по одному на каждый месяц.

Месяцы с 1 по 12 для января-декабря.

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

Попросите, чтобы объект сгенерировал строку с именем месяца, автоматически локализованную .

Настройте TextStyle, чтобы указать, как долго или сокращенно вы хотите название. Обратите внимание, что на некоторых языках (не на английском) название месяца меняется, если используется отдельно или как часть полной даты. Таким образом, каждый стиль текста имеет вариант …_STANDALONE.

Укажите Locale, чтобы определить:

  • Какой человеческий язык следует использовать при переводе.
  • Какие культурные нормы должны решать такие вопросы, как аббревиатура, пунктуация и капитализация.
* +1037 * Пример:
Locale l = new Locale( "es" , "MX" );
String output = Month.FEBRUARY.getDisplayName( TextStyle.SHORT_STANDALONE , l );  // Or Locale.US, Locale.CANADA_FRENCH. 

Имя → Month Объект

К вашему сведению, движение в другом направлении (анализ строки имени месяца для получения объекта перечисления Month) не является встроенным. Вы можете написать свой собственный класс для этого. Вот моя быстрая попытка в таком классе. Используйте на свой страх и риск . Я не придавал этому коду серьезных мыслей и серьезных испытаний.

Usage.

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

код.

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." );
        }
    }
}

О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют старые классные устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Вы можете обмениваться java.time объектами напрямую с вашей базой данных. Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где получить классы java.time?

  • Java SE 8 , Java SE 9 и выше
    • Встроенный.
    • Часть стандартного Java API с встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функций java.time перенесена на Java 6 и 7 в ThreeTen-Backport .
  • Android

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и more .

1 голос
/ 09 марта 2015

Существует проблема, когда вы используете класс DateFormatSymbols для его метода getMonthName, чтобы получить Месяц по имени и показать Месяц по номеру на некоторых устройствах Android. Я решил эту проблему следующим образом:

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>

В классе Java просто вызовите этот массив следующим образом:

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:)

0 голосов
/ 17 мая 2019

Попробуйте использовать этот очень простой способ и назовите его своим собственным функционалом

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;
     }
...