Вопрос по date, java, locale – Как я могу преобразовать Integer в локализованное название месяца в Java?

88

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

Пример для локали en-us:
1 - & gt; январь
2 - & gt; февраль

Пример для локали es-mx:
1 - & gt; Enero
2 - & gt; Febrero

Вы правы, поэтому, если вам нужно изменить язык, просто нужно изменить язык. Спасибо atomsfat
Обратите внимание, месяцы Java начинаются с нуля, поэтому 0 = январь, 1 = февраль и т. Д. Nick Holt
@NickHoltUPDATE Современныйjava.timeMonth enum является односторонним: 1-12 для января-декабря. То же самое для [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 Календарь имеет сумасшедшие схемы нумерации. Одна из многих причин избегать устаревших классов, теперь полностью вытесненныхjava.time классы. Basil Bourque

Ваш Ответ

11   ответов
12
java.time

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

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

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

скажем, у вас есть String Month of May на французском языке, используя метод, который вы опубликовали (May на французском языке - Mai), как я могу получить число 5 из этой строки ??
@usertest Я написал черновик классаMonthDelocalizer вmy Answer чтобы получитьMonth объект из переданной локализованной строки названия месяца:mai & # X2192; Месяц май. Обратите внимание, что чувствительность к регистру имеет значение: на французском языкеMai недействителен и должен бытьmai.
0

Просто вставляю строку

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

сделает свое дело.

Спасибо @BasilBourque. Это хорошо отмечено.
Этот ответ дублирует содержаниеthe accepted Answer.
DateFormatSymbols является частью ужасных классов даты и времени, которые теперь унаследованы, с момента принятияJSR 310, Теперь вытесненыjava.time классы. Предлагать их использование в 2019 году - плохой совет.
189
import java.text.DateFormatSymbols;
public String getMonth(int month) {
    return new DateFormatSymbols().getMonths()[month-1];
}
Ему нужен месяц-1, потому что месяц - это номер месяца, основанный на 1, который необходимо преобразовать в позицию массива, начинающуюся с нуля.
Реализация DateFormatSymbols была изменена в JDK 8, поэтому метод getMonths больше не возвращает правильных значений для всех Locale:oracle.com/technetwork/java/javase/…
HE потребностиmonth-1, Кто-нибудь еще используетCalendar.get(Calendar.MONTH) просто нужноmonth
Вам не нужен «месяц-1», так как массив основан на нуле? atomfat хочет 1 - & gt; Январь и т. Д.
public String getMonth (int month, языковой стандарт Locale) {return DateFormatSymbols.getInstance (locale) .getMonths () [month-1]; } atomsfat
15

если есть более простой способ составления календаря, хотя я делаю это сейчас в коде, и я не уверен в этом.

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());
}
& Quot; MMMM & Quot; достаточно.
13

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];
}
0
    public static void main(String[] args) {
    SimpleDateFormat format = new SimpleDateFormat("MMMMM", new Locale("en", "US"));
    System.out.println(format.format(new Date()));
}
Я делаю так, потому что считаю простым и не сложным!
похоже, это правильный ответ, но можете ли вы объяснить, что вы делаете и почему вы делаете это таким образом?
1

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

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

            }

Удачного кодирования :)

5
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

которые вытесняют эти проблемные старые унаследованные классы даты и времени.

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

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

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

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

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

УкажитеLocale определить:

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

Пример:

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

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

Использование.

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

java.time фреймворк встроен в Java 8 и выше. Эти классы вытесняют хлопотное староенаследие классы даты и времени, такие какjava.util.Date, Calendar& amp;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, and later Built-in. Part of the standard Java API with a bundled implementation. Java 9 adds some minor features and fixes. Java SE 6 and Java SE 7 Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport. Android Later versions of Android bundle implementations of the java.time classes. For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

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

7

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

<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;
}
"Apparently in Android 2.2 there is a bug" & # X2014; Было бы полезно, если бы вы могли указать, где ошибка отслеживается.
10

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

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

31

ументировано вSimpleDateFormat документация, такая как:

SimpleDateFormat dateFormat = new SimpleDateFormat( "LLLL", Locale.getDefault() );
dateFormat.format( date );
JDK 1,7 /IllegalArgumentException : Illegal pattern character 'L'

Похожие вопросы