Я получаю целое число, и мне нужно преобразовать в названия месяцев в разных языках:
Пример для locale en-us:
1 ->
2 января -> февраль
Пример для locale es-mx:
1 -> Enero
2 -> Febrero
Я получаю целое число, и мне нужно преобразовать в названия месяцев в разных языках:
Пример для locale en-us:
1 ->
2 января -> февраль
Пример для locale es-mx:
1 -> Enero
2 -> Febrero
java.timeMonth
перечисление основано на единице: 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
Calendar` имеет сумасшедшие схемы нумерации. Одна из многих причин избегать устаревших классов, которые теперь полностью вытеснены классами java.time .
Ответы:
import java.text.DateFormatSymbols;
public String getMonth(int month) {
return new DateFormatSymbols().getMonths()[month-1];
}
month-1
. Кто-нибудь еще, использующий, Calendar.get(Calendar.MONTH)
будет просто нуждатьсяmonth
Вам необходимо использовать LLLL для автономных названий месяцев. это задокументировано в SimpleDateFormat
документации, например:
SimpleDateFormat dateFormat = new SimpleDateFormat( "LLLL", Locale.getDefault() );
dateFormat.format( date );
IllegalArgumentException : Illegal pattern character 'L'
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 1.8 (или 1.7 и 1.6 с ThreeTen-Backport ) вы можете использовать это:
Month.of(integerMonth).getDisplayName(TextStyle.FULL_STANDALONE, locale);
Обратите внимание, что integerMonth
отсчитывается от 1, т.е. 1 соответствует январю. Диапазон всегда от 1 до 12 для января-декабря (т. Е. Только по григорианскому календарю).
MonthDelocalizer
в моем ответе , чтобы получить Month
объект из прошедшей локализованного имени месяца строки: mai
→ Month.MAY. Обратите внимание, что чувствительность к регистру имеет значение: во французском языке Mai
это недопустимо и должно быть mai
.
Я бы использовал 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());
}
Вот как бы я это сделал. Я оставлю проверку дальности 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];
}
Использование 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");
Результат: февраль
Видимо в 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;
}
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
чтобы определить:
Пример:
Locale l = new Locale( "es" , "MX" );
String output = Month.FEBRUARY.getDisplayName( TextStyle.SHORT_STANDALONE , l ); // Or Locale.US, Locale.CANADA_FRENCH.
Month
объектFYI, пойти в другом направлении (разбор строки имени месяца для получения Month
объекта перечисления) не встроен. Вы можете написать свой собственный класс для этого. Вот моя быстрая попытка пройти такой урок.Используйте на свой риск . Я не задумывался над этим кодом и не тестировал его.
Использование.
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 8 и более поздних версий. Эти классы вытеснять неприятные старые устаревшие классы даты и времени , такие как java.util.Date
, Calendar
, иSimpleDateFormat
.
Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time .
Чтобы узнать больше, см. Oracle Tutorial . И поищите в Stack Overflow множество примеров и объяснений. Спецификация JSR 310 .
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в java.sql.*
занятиях.
Где взять классы java.time?
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательной площадкой для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как Interval
, YearWeek
, YearQuarter
, и более .
Возникает проблема, когда вы используете класс 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);
}
Удачного кодирования :)
Расширение Kotlin
fun Int.toMonthName(): String {
return DateFormatSymbols().months[this]
}
использование
calendar.get(Calendar.MONTH).toMonthName()
Calendar
класс был вытеснен много лет назад классами java.time, определенными в JSR 310.
public static void main(String[] args) {
SimpleDateFormat format = new SimpleDateFormat("MMMMM", new Locale("en", "US"));
System.out.println(format.format(new Date()));
}
SimpleDateFormat
Тем не менее, он использует заведомо проблемный и давно устаревший класс.
Просто вставив строку
DateFormatSymbols.getInstance().getMonths()[view.getMonth()]
сделает свое дело.
DateFormatSymbols
является частью ужасных классов даты и времени, которые теперь унаследованы с момента принятия JSR 310 . Теперь на смену классам java.time . Предлагать их использование в 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;
}
Month::getDisplayName
.